From 807fbb473f86d9f07f7b374a8b687c82ffb4572c Mon Sep 17 00:00:00 2001 From: Francisco Magdaleno Arceo Date: Thu, 20 Feb 2020 11:22:31 -0800 Subject: [PATCH 01/17] Add dart file --- .../path_provider/path_provider_macos/lib/path_provider.dart | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 packages/path_provider/path_provider_macos/lib/path_provider.dart diff --git a/packages/path_provider/path_provider_macos/lib/path_provider.dart b/packages/path_provider/path_provider_macos/lib/path_provider.dart new file mode 100644 index 000000000000..cf440b2858af --- /dev/null +++ b/packages/path_provider/path_provider_macos/lib/path_provider.dart @@ -0,0 +1,3 @@ +// Analyze will fail if there is no main.dart file. This file should +// be removed once an example app has been added to path_provider_macos. +// https://github.com/flutter/flutter/issues/51007 From 47488617fac4e4c6c787aa00051390253cb3a0a8 Mon Sep 17 00:00:00 2001 From: Francisco Magdaleno Arceo Date: Thu, 20 Feb 2020 12:43:48 -0800 Subject: [PATCH 02/17] Rename file --- .../path_provider/path_provider_macos/lib/path_provider.dart | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 packages/path_provider/path_provider_macos/lib/path_provider.dart diff --git a/packages/path_provider/path_provider_macos/lib/path_provider.dart b/packages/path_provider/path_provider_macos/lib/path_provider.dart deleted file mode 100644 index cf440b2858af..000000000000 --- a/packages/path_provider/path_provider_macos/lib/path_provider.dart +++ /dev/null @@ -1,3 +0,0 @@ -// Analyze will fail if there is no main.dart file. This file should -// be removed once an example app has been added to path_provider_macos. -// https://github.com/flutter/flutter/issues/51007 From c40e8130214021a57e63abf8cd86c5abf3ec0b65 Mon Sep 17 00:00:00 2001 From: Francisco Magdaleno Arceo Date: Thu, 20 Feb 2020 13:43:15 -0800 Subject: [PATCH 03/17] add interface, rename files, add methods to class --- .../CHANGELOG.md | 3 + .../path_provider_platform_interface/LICENSE | 27 ++++++ .../README.md | 26 +++++ .../lib/path_provider_platform_interface.dart | 95 +++++++++++++++++++ .../lib/src/enums.dart | 49 ++++++++++ .../lib/src/method_channel_path_provider.dart | 18 ++++ .../pubspec.yaml | 20 ++++ .../method_channel_path_provider_test.dart | 0 8 files changed, 238 insertions(+) create mode 100644 packages/path_provider/path_provider_platform_interface/CHANGELOG.md create mode 100644 packages/path_provider/path_provider_platform_interface/LICENSE create mode 100644 packages/path_provider/path_provider_platform_interface/README.md create mode 100644 packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart create mode 100644 packages/path_provider/path_provider_platform_interface/lib/src/enums.dart create mode 100644 packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart create mode 100644 packages/path_provider/path_provider_platform_interface/pubspec.yaml create mode 100644 packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart diff --git a/packages/path_provider/path_provider_platform_interface/CHANGELOG.md b/packages/path_provider/path_provider_platform_interface/CHANGELOG.md new file mode 100644 index 000000000000..0d8803f93540 --- /dev/null +++ b/packages/path_provider/path_provider_platform_interface/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +* Initial release. diff --git a/packages/path_provider/path_provider_platform_interface/LICENSE b/packages/path_provider/path_provider_platform_interface/LICENSE new file mode 100644 index 000000000000..0c91662b3f2f --- /dev/null +++ b/packages/path_provider/path_provider_platform_interface/LICENSE @@ -0,0 +1,27 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/path_provider/path_provider_platform_interface/README.md b/packages/path_provider/path_provider_platform_interface/README.md new file mode 100644 index 000000000000..50035db91482 --- /dev/null +++ b/packages/path_provider/path_provider_platform_interface/README.md @@ -0,0 +1,26 @@ +# path_provider_platform_interface + +A common platform interface for the [`path_provider`][1] plugin. + +This interface allows platform-specific implementations of the `path_provider` +plugin, as well as the plugin itself, to ensure they are supporting the +same interface. + +# Usage + +To implement a new platform-specific implementation of `path_provider`, extend +[`PathProviderPlatform`][2] with an implementation that performs the +platform-specific behavior, and when you register your plugin, set the default +`PathProviderPlatform` by calling +`PathProviderPlatform.instance = MyPlatformPathProvider()`. + +# Note on breaking changes + +Strongly prefer non-breaking changes (such as adding a method to the interface) +over breaking changes for this package. + +See https://flutter.dev/go/platform-interface-breaking-changes for a discussion +on why a less-clean interface is preferable to a breaking change. + +[1]: ../ +[2]: lib/path_provider_platform_interface.dart diff --git a/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart new file mode 100644 index 000000000000..511f9d1941e9 --- /dev/null +++ b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart @@ -0,0 +1,95 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; +import 'dart:io' show Directory; + +import 'src/enums.dart'; +import 'src/method_channel_path_provider.dart'; + +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +/// The interface that implementations of path_provider must implement. +/// +/// Platform implementations should extend this class rather than implement it as `PathProvider` +/// does not consider newly added methods to be breaking changes. Extending this class +/// (using `extends`) ensures that the subclass will get the default implementation, while +/// platform implementations that `implements` this interface will be broken by newly added +/// [PathProviderPlatform] methods. +abstract class PathProviderPlatform extends PlatformInterface { + /// Constructs a PathProviderPlatform. + PathProviderPlatform() : super(token: _token); + + static final Object _token = Object(); + + static PathProviderPlatform _instance = MethodChannelPathProvider(); + + /// The default instance of [PathProviderPlatform] to use. + /// + /// Defaults to [MethodChannelPathProvider]. + static PathProviderPlatform get instance => _instance; + + /// Platform-specific plugins should set this with their own platform-specific + /// class that extends [PathProviderPlatform] when they register themselves. + static set instance(PathProviderPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + /// Path to the temporary directory on the device that is not backed up and is + /// suitable for storing caches of downloaded files. + Future getTemporaryDirectory() { + throw UnimplementedError('getTemporaryDirectory() has not been implemented.'); + } + /// Path to a directory where the application may place application support + /// files. + Future getApplicationSupportDirectory() { + throw UnimplementedError('getApplicationSupportDirectory() has not been implemented.'); + } + + /// Path to the directory where application can store files that are persistent, + /// backed up, and not visible to the user, such as sqlite.db. + Future getLibraryDirectory() { + throw UnimplementedError('getLibraryDirectory() has not been implemented.'); + } + + /// Path to a directory where the application may place data that is + /// user-generated, or that cannot otherwise be recreated by your application. + Future getApplicationDocumentsDirectory() { + throw UnimplementedError('getApplicationDocumentsDirectory() has not been implemented.'); + } + + /// Path to a directory where the application may access top level storage. + /// The current operating system should be determined before issuing this + /// function call, as this functionality is only available on Android. + Future getExternalStorageDirectory() { + throw UnimplementedError('getExternalStorageDirectory() has not been implemented.'); + } + + /// Paths to directories where application specific external cache data can be + /// stored. These paths typically reside on external storage like separate + /// partitions or SD cards. Phones may have multiple storage directories + /// available. + Future> getExternalCacheDirectories() { + throw UnimplementedError('getExternalCacheDirectories() has not been implemented.'); + } + + /// Paths to directories where application specific data can be stored. + /// These paths typically reside on external storage like separate partitions + /// or SD cards. Phones may have multiple storage directories available. + Future> getExternalStorageDirectories({ + /// Optional parameter. See [AndroidStorageDirectory] for more informations on + /// how this type translates to Android storage directories. + AndroidStorageDirectory type, + }) { + throw UnimplementedError('getExternalStorageDirectories() has not been implemented.'); + } + + + /// Path to the directory where downloaded files can be stored. + /// This is typically only relevant on desktop operating systems. + Future getDownloadsDirectory() { + throw UnimplementedError('getDownloadsDirectory() has not been implemented.'); + } +} diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart b/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart new file mode 100644 index 000000000000..cf04a164203f --- /dev/null +++ b/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart @@ -0,0 +1,49 @@ +/// Corresponds to constants defined in Androids `android.os.Environment` class. +/// +/// https://developer.android.com/reference/android/os/Environment.html#fields_1 +enum AndroidStorageDirectory { + /// Contains audio files that should be treated as music. + /// + /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_MUSIC. + music, + + /// Contains audio files that should be treated as podcasts. + /// + /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_PODCASTS. + podcasts, + + /// Contains audio files that should be treated as ringtones. + /// + /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_RINGTONES. + ringtones, + + /// Contains audio files that should be treated as alarm sounds. + /// + /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_ALARMS. + alarms, + + /// Contains audio files that should be treated as notification sounds. + /// + /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_NOTIFICATIONS. + notifications, + + /// Contains images. See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_PICTURES. + pictures, + + /// Contains movies. See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_MOVIES. + movies, + + /// Contains files of any type that have been downloaded by the user. + /// + /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_DOWNLOADS. + downloads, + + /// Used to hold both pictures and videos when the device filesystem is + /// treated like a camera's. + /// + /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_DCIM. + dcim, + + /// Holds user-created documents. See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_DOCUMENTS. + documents, +} diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart new file mode 100644 index 000000000000..ae015fd490db --- /dev/null +++ b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart @@ -0,0 +1,18 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; +import 'dart:io' show Platform; + +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart'; + +/// An implementation of [PathProviderPlatform] that uses method channels. +class MethodChannelPathProvider extends PathProviderPlatform { + /// The method channel used to interact with the native platform. + @visibleForTesting + MethodChannel methodChannel = + MethodChannel('plugins.flutter.io/path_provider'); +} diff --git a/packages/path_provider/path_provider_platform_interface/pubspec.yaml b/packages/path_provider/path_provider_platform_interface/pubspec.yaml new file mode 100644 index 000000000000..4244d1d1ae02 --- /dev/null +++ b/packages/path_provider/path_provider_platform_interface/pubspec.yaml @@ -0,0 +1,20 @@ +name: path_provider_platform_interface +description: A common platform interface for the path_provider plugin. +homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_platform_interface +# NOTE: We strongly prefer non-breaking changes, even at the expense of a +# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes +version: 1.0.2 + +dependencies: + flutter: + sdk: flutter + meta: ^1.0.5 + plugin_platform_interface: ^1.0.1 + +dev_dependencies: + flutter_test: + sdk: flutter + +environment: + sdk: ">=2.0.0-dev.28.0 <3.0.0" + flutter: ">=1.10.0 <2.0.0" diff --git a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart new file mode 100644 index 000000000000..e69de29bb2d1 From b049781cd7806d7a9087740e95b0921e85503f2d Mon Sep 17 00:00:00 2001 From: Francisco Magdaleno Arceo Date: Thu, 20 Feb 2020 14:52:19 -0800 Subject: [PATCH 04/17] Add to method channel, not done --- .../lib/src/method_channel_path_provider.dart | 88 ++++++++++++++++++- 1 file changed, 86 insertions(+), 2 deletions(-) diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart index ae015fd490db..e0f73b26760b 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart @@ -3,11 +3,12 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:io' show Platform; +import 'dart:io' show Directory; -import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; import 'package:flutter/services.dart'; import 'package:meta/meta.dart'; +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; +import 'package:platform/platform.dart'; /// An implementation of [PathProviderPlatform] that uses method channels. class MethodChannelPathProvider extends PathProviderPlatform { @@ -15,4 +16,87 @@ class MethodChannelPathProvider extends PathProviderPlatform { @visibleForTesting MethodChannel methodChannel = MethodChannel('plugins.flutter.io/path_provider'); + + // TODO(franciscojma): Remove once all the platforms have been moved to its own package and endorsed. + Platform _platform = const LocalPlatform(); + + /// This API is only exposed for the unit tests. It should not be used by + /// any code outside of the plugin itself. + @visibleForTesting + void setMockPathProviderPlatform(Platform platform) { + _platform = platform; +} + + Future getTemporaryDirectory() async { + final String path = + await methodChannel.invokeMethod('getTemporaryDirectory'); + if (path == null) { + return null; + } + return Directory(path); + } + + Future getApplicationSupportDirectory() async { + final String path = + await _channel.invokeMethod('getApplicationSupportDirectory'); + if (path == null) { + return null; + } + + return Directory(path); + } + + /// Path to the directory where application can store files that are persistent, + /// backed up, and not visible to the user, such as sqlite.db. + Future getLibraryDirectory() async { + if (!_platform.isIOS || !_platform.isMacOS) { + throw UnsupportedError('Functionality only available on iOS/macOS'); + } + final String path = + await _channel.invokeMethod('getLibraryDirectory'); + if (path == null) { + return null; + } + return Directory(path); + } + + Future getApplicationDocumentsDirectory() async { + final String path = + await _channel.invokeMethod('getApplicationDocumentsDirectory'); + if (path == null) { + return null; + } + return Directory(path); + } + + Future getExternalStorageDirectory() { + if (!_platform.ispath); + } + + /// Paths to directories where application specific external cache data can be + /// stored. These paths typically reside on external storage like separate + /// partitions or SD cards. Phones may have multiple storage directories + /// available. + Future> getExternalCacheDirectories() { + throw UnimplementedError('getExternalCacheDirectories() has not been implemented.'); + } + + /// Paths to directories where application specific data can be stored. + /// These paths typically reside on external storage like separate partitions + /// or SD cards. Phones may have multiple storage directories available. + Future> getExternalStorageDirectories({ + /// Optional parameter. See [AndroidStorageDirectory] for more informations on + /// how this type translates to Android storage directories. + AndroidStorageDirectory type, + }) { + throw UnimplementedError('getExternalStorageDirectories() has not been implemented.'); + } + + + /// Path to the directory where downloaded files can be stored. + /// This is typically only relevant on desktop operating systems. + Future getDownloadsDirectory() { + throw UnimplementedError('getDownloadsDirectory() has not been implemented.'); + } + } From 7543c0c8d8004aa5f1bdfefe73e1450bb9c3d714 Mon Sep 17 00:00:00 2001 From: Francisco Magdaleno Arceo Date: Thu, 20 Feb 2020 11:22:31 -0800 Subject: [PATCH 05/17] Add dart file --- .../path_provider/path_provider_macos/lib/path_provider.dart | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 packages/path_provider/path_provider_macos/lib/path_provider.dart diff --git a/packages/path_provider/path_provider_macos/lib/path_provider.dart b/packages/path_provider/path_provider_macos/lib/path_provider.dart new file mode 100644 index 000000000000..cf440b2858af --- /dev/null +++ b/packages/path_provider/path_provider_macos/lib/path_provider.dart @@ -0,0 +1,3 @@ +// Analyze will fail if there is no main.dart file. This file should +// be removed once an example app has been added to path_provider_macos. +// https://github.com/flutter/flutter/issues/51007 From d4f1ba5a51954c4ef4b6206d6693cb8aa0cfd404 Mon Sep 17 00:00:00 2001 From: Francisco Magdaleno Arceo Date: Thu, 20 Feb 2020 12:43:48 -0800 Subject: [PATCH 06/17] Rename file --- .../path_provider/path_provider_macos/lib/path_provider.dart | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 packages/path_provider/path_provider_macos/lib/path_provider.dart diff --git a/packages/path_provider/path_provider_macos/lib/path_provider.dart b/packages/path_provider/path_provider_macos/lib/path_provider.dart deleted file mode 100644 index cf440b2858af..000000000000 --- a/packages/path_provider/path_provider_macos/lib/path_provider.dart +++ /dev/null @@ -1,3 +0,0 @@ -// Analyze will fail if there is no main.dart file. This file should -// be removed once an example app has been added to path_provider_macos. -// https://github.com/flutter/flutter/issues/51007 From 02b038a8e3ece6a79b36d7feb90084de4299d428 Mon Sep 17 00:00:00 2001 From: Francisco Magdaleno Arceo Date: Mon, 24 Feb 2020 17:35:58 -0800 Subject: [PATCH 07/17] Adds method channel test --- .../lib/path_provider_platform_interface.dart | 23 ++-- .../lib/src/method_channel_path_provider.dart | 69 ++++++++---- .../pubspec.yaml | 3 + .../method_channel_path_provider_test.dart | 101 ++++++++++++++++++ 4 files changed, 170 insertions(+), 26 deletions(-) diff --git a/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart index 511f9d1941e9..77bc39d88116 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart @@ -40,12 +40,15 @@ abstract class PathProviderPlatform extends PlatformInterface { /// Path to the temporary directory on the device that is not backed up and is /// suitable for storing caches of downloaded files. Future getTemporaryDirectory() { - throw UnimplementedError('getTemporaryDirectory() has not been implemented.'); + throw UnimplementedError( + 'getTemporaryDirectory() has not been implemented.'); } + /// Path to a directory where the application may place application support /// files. Future getApplicationSupportDirectory() { - throw UnimplementedError('getApplicationSupportDirectory() has not been implemented.'); + throw UnimplementedError( + 'getApplicationSupportDirectory() has not been implemented.'); } /// Path to the directory where application can store files that are persistent, @@ -57,14 +60,16 @@ abstract class PathProviderPlatform extends PlatformInterface { /// Path to a directory where the application may place data that is /// user-generated, or that cannot otherwise be recreated by your application. Future getApplicationDocumentsDirectory() { - throw UnimplementedError('getApplicationDocumentsDirectory() has not been implemented.'); + throw UnimplementedError( + 'getApplicationDocumentsDirectory() has not been implemented.'); } /// Path to a directory where the application may access top level storage. /// The current operating system should be determined before issuing this /// function call, as this functionality is only available on Android. Future getExternalStorageDirectory() { - throw UnimplementedError('getExternalStorageDirectory() has not been implemented.'); + throw UnimplementedError( + 'getExternalStorageDirectory() has not been implemented.'); } /// Paths to directories where application specific external cache data can be @@ -72,7 +77,8 @@ abstract class PathProviderPlatform extends PlatformInterface { /// partitions or SD cards. Phones may have multiple storage directories /// available. Future> getExternalCacheDirectories() { - throw UnimplementedError('getExternalCacheDirectories() has not been implemented.'); + throw UnimplementedError( + 'getExternalCacheDirectories() has not been implemented.'); } /// Paths to directories where application specific data can be stored. @@ -83,13 +89,14 @@ abstract class PathProviderPlatform extends PlatformInterface { /// how this type translates to Android storage directories. AndroidStorageDirectory type, }) { - throw UnimplementedError('getExternalStorageDirectories() has not been implemented.'); + throw UnimplementedError( + 'getExternalStorageDirectories() has not been implemented.'); } - /// Path to the directory where downloaded files can be stored. /// This is typically only relevant on desktop operating systems. Future getDownloadsDirectory() { - throw UnimplementedError('getDownloadsDirectory() has not been implemented.'); + throw UnimplementedError( + 'getDownloadsDirectory() has not been implemented.'); } } diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart index e0f73b26760b..b0a18f777a15 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart @@ -5,10 +5,14 @@ import 'dart:async'; import 'dart:io' show Directory; +import 'enums.dart'; +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; + import 'package:flutter/services.dart'; import 'package:meta/meta.dart'; import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; import 'package:platform/platform.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; /// An implementation of [PathProviderPlatform] that uses method channels. class MethodChannelPathProvider extends PathProviderPlatform { @@ -25,7 +29,7 @@ class MethodChannelPathProvider extends PathProviderPlatform { @visibleForTesting void setMockPathProviderPlatform(Platform platform) { _platform = platform; -} + } Future getTemporaryDirectory() async { final String path = @@ -37,8 +41,8 @@ class MethodChannelPathProvider extends PathProviderPlatform { } Future getApplicationSupportDirectory() async { - final String path = - await _channel.invokeMethod('getApplicationSupportDirectory'); + final String path = await methodChannel + .invokeMethod('getApplicationSupportDirectory'); if (path == null) { return null; } @@ -49,11 +53,12 @@ class MethodChannelPathProvider extends PathProviderPlatform { /// Path to the directory where application can store files that are persistent, /// backed up, and not visible to the user, such as sqlite.db. Future getLibraryDirectory() async { - if (!_platform.isIOS || !_platform.isMacOS) { + print(_platform.isAndroid); + if (!_platform.isIOS && !_platform.isMacOS) { throw UnsupportedError('Functionality only available on iOS/macOS'); } final String path = - await _channel.invokeMethod('getLibraryDirectory'); + await methodChannel.invokeMethod('getLibraryDirectory'); if (path == null) { return null; } @@ -61,42 +66,70 @@ class MethodChannelPathProvider extends PathProviderPlatform { } Future getApplicationDocumentsDirectory() async { - final String path = - await _channel.invokeMethod('getApplicationDocumentsDirectory'); + final String path = await methodChannel + .invokeMethod('getApplicationDocumentsDirectory'); if (path == null) { return null; } return Directory(path); } - Future getExternalStorageDirectory() { - if (!_platform.ispath); + Future getExternalStorageDirectory() async { + if (!_platform.isAndroid) { + throw UnsupportedError('Functionality only available on Android'); + } + final String path = + await methodChannel.invokeMethod('getStorageDirectory'); + if (path == null) { + return null; + } + return Directory(path); } /// Paths to directories where application specific external cache data can be /// stored. These paths typically reside on external storage like separate /// partitions or SD cards. Phones may have multiple storage directories /// available. - Future> getExternalCacheDirectories() { - throw UnimplementedError('getExternalCacheDirectories() has not been implemented.'); + Future> getExternalCacheDirectories() async { + if (!_platform.isAndroid) { + throw UnsupportedError('Functionality only available on Android'); + } + final List paths = await methodChannel + .invokeListMethod('getExternalCacheDirectories'); + + return paths.map((String path) => Directory(path)).toList(); } /// Paths to directories where application specific data can be stored. /// These paths typically reside on external storage like separate partitions /// or SD cards. Phones may have multiple storage directories available. Future> getExternalStorageDirectories({ - /// Optional parameter. See [AndroidStorageDirectory] for more informations on + /// Optional parameter. See [StorageDirectory] for more informations on /// how this type translates to Android storage directories. AndroidStorageDirectory type, - }) { - throw UnimplementedError('getExternalStorageDirectories() has not been implemented.'); - } + }) async { + if (!_platform.isAndroid) { + throw UnsupportedError('Functionality only available on Android'); + } + final List paths = await methodChannel.invokeListMethod( + 'getExternalStorageDirectories', + {'type': type?.index}, + ); + return paths.map((String path) => Directory(path)).toList(); + } /// Path to the directory where downloaded files can be stored. /// This is typically only relevant on desktop operating systems. - Future getDownloadsDirectory() { - throw UnimplementedError('getDownloadsDirectory() has not been implemented.'); + Future getDownloadsDirectory() async { + if (!_platform.isMacOS) { + throw UnsupportedError('Functionality only available on macOS'); + } + final String path = + await methodChannel.invokeMethod('getDownloadsDirectory'); + if (path == null) { + return null; + } + return Directory(path); } - } diff --git a/packages/path_provider/path_provider_platform_interface/pubspec.yaml b/packages/path_provider/path_provider_platform_interface/pubspec.yaml index 4244d1d1ae02..79d3b878bf4f 100644 --- a/packages/path_provider/path_provider_platform_interface/pubspec.yaml +++ b/packages/path_provider/path_provider_platform_interface/pubspec.yaml @@ -9,11 +9,14 @@ dependencies: flutter: sdk: flutter meta: ^1.0.5 + platform: ^2.0.0 plugin_platform_interface: ^1.0.1 dev_dependencies: flutter_test: sdk: flutter + pedantic: ^1.8.0 + test: any environment: sdk: ">=2.0.0-dev.28.0 <3.0.0" diff --git a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart index e69de29bb2d1..72d574349ea8 100644 --- a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart +++ b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart @@ -0,0 +1,101 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:io' show Directory; + +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:path_provider_platform_interface/src/method_channel_path_provider.dart'; +import 'package:platform/platform.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + const String kTemporaryDirectory = 'temporaryDirectory'; + const String kApplicationSupportDirectory = 'applicationSupportDirectory'; + const String kLibraryDirectory = 'libraryDirectory'; + const String kApplicationDocumentsDirectory = 'applicationDocumentsDirectory'; + const String kExternalCacheDirectories = 'externalCacheDirectories'; + const String kExternalStorageDirectories = 'externalStorageDirectories'; + const String kDownloadsDirectory = 'downloadsDirectory'; + + group('$MethodChannelPathProvider', () { + MethodChannelPathProvider methodChannelPathProvider; + + setUp(() async { + methodChannelPathProvider = MethodChannelPathProvider(); + + methodChannelPathProvider.methodChannel + .setMockMethodCallHandler((MethodCall methodCall) async { + switch (methodCall.method) { + case 'getTemporaryDirectory': + return kTemporaryDirectory; + case 'getApplicationSupportDirectory': + return kApplicationSupportDirectory; + case 'getLibraryDirectory': + return kLibraryDirectory; + case 'getApplicationDocumentsDirectory': + return kApplicationDocumentsDirectory; + case 'getExternalStorageDirectories': + return [kExternalStorageDirectories]; + case 'getExternalCacheDirectories': + return [kExternalCacheDirectories]; + case 'getDownloadsDirectory': + return kDownloadsDirectory; + default: + return null; + } + }); + }); + + test('getTemporaryDirectory', () async { + final Directory result = + await methodChannelPathProvider.getTemporaryDirectory(); + expect(result.path, kTemporaryDirectory); + }); + test('getApplicationSupportDirectory', () async { + final Directory result = + await methodChannelPathProvider.getApplicationSupportDirectory(); + expect(result.path, kApplicationSupportDirectory); + }); + + test('getLibraryDirectory', () async { + methodChannelPathProvider + .setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); + final Directory result = + await methodChannelPathProvider.getLibraryDirectory(); + expect(result.path, kLibraryDirectory); + }); + test('getApplicationDocumentsDirectory', () async { + final Directory result = + await methodChannelPathProvider.getApplicationDocumentsDirectory(); + expect(result.path, kApplicationDocumentsDirectory); + }); + test('getExternalCacheDirectories', () async { + methodChannelPathProvider.setMockPathProviderPlatform( + FakePlatform(operatingSystem: 'android')); + final List result = + await methodChannelPathProvider.getExternalCacheDirectories(); + + expect(result.length, 1); + expect(result.first.path, kExternalCacheDirectories); + }); + test('getExternalStorageDirectories', () async { + methodChannelPathProvider.setMockPathProviderPlatform( + FakePlatform(operatingSystem: 'android')); + final List result = + await methodChannelPathProvider.getExternalStorageDirectories(); + + expect(result.length, 1); + expect(result.first.path, kExternalStorageDirectories); + }); + test('getDownloadsDirectory', () async { + methodChannelPathProvider + .setMockPathProviderPlatform(FakePlatform(operatingSystem: 'macos')); + final Directory result = + await methodChannelPathProvider.getDownloadsDirectory(); + + expect(result.path, kDownloadsDirectory); + }); + }); +} From 678dd5d733a80108576fab96e5aaaae8932a3dd4 Mon Sep 17 00:00:00 2001 From: Francisco Magdaleno Arceo Date: Mon, 24 Feb 2020 17:40:39 -0800 Subject: [PATCH 08/17] Remove prints --- .../lib/src/method_channel_path_provider.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart index b0a18f777a15..ee57a16fe840 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart @@ -53,7 +53,6 @@ class MethodChannelPathProvider extends PathProviderPlatform { /// Path to the directory where application can store files that are persistent, /// backed up, and not visible to the user, such as sqlite.db. Future getLibraryDirectory() async { - print(_platform.isAndroid); if (!_platform.isIOS && !_platform.isMacOS) { throw UnsupportedError('Functionality only available on iOS/macOS'); } From d88af02108f771d8f662639fc1ffc0dd5225873d Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Tue, 25 Feb 2020 09:46:10 -0800 Subject: [PATCH 09/17] Fix imports and version --- .../lib/src/method_channel_path_provider.dart | 2 -- .../path_provider/path_provider_platform_interface/pubspec.yaml | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart index ee57a16fe840..0fb387b4a728 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart @@ -6,13 +6,11 @@ import 'dart:async'; import 'dart:io' show Directory; import 'enums.dart'; -import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; import 'package:flutter/services.dart'; import 'package:meta/meta.dart'; import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; import 'package:platform/platform.dart'; -import 'package:plugin_platform_interface/plugin_platform_interface.dart'; /// An implementation of [PathProviderPlatform] that uses method channels. class MethodChannelPathProvider extends PathProviderPlatform { diff --git a/packages/path_provider/path_provider_platform_interface/pubspec.yaml b/packages/path_provider/path_provider_platform_interface/pubspec.yaml index 79d3b878bf4f..44bc0c2c161c 100644 --- a/packages/path_provider/path_provider_platform_interface/pubspec.yaml +++ b/packages/path_provider/path_provider_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the path_provider plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.0.2 +version: 1.0.0 dependencies: flutter: From 70cffb0b35c4e54104cc435a43802e3d19ef4ba9 Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Tue, 25 Feb 2020 10:03:36 -0800 Subject: [PATCH 10/17] Format and commentas --- .../lib/src/method_channel_path_provider.dart | 17 +++-------------- .../test/method_channel_path_provider_test.dart | 5 +++++ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart index 0fb387b4a728..29ae0073bffb 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart @@ -19,7 +19,9 @@ class MethodChannelPathProvider extends PathProviderPlatform { MethodChannel methodChannel = MethodChannel('plugins.flutter.io/path_provider'); - // TODO(franciscojma): Remove once all the platforms have been moved to its own package and endorsed. + // Ideally, this property shouldn't exist, and each platform should + // just implement the supported methods. Once all the platforms are + // federated, this property should be removed. Platform _platform = const LocalPlatform(); /// This API is only exposed for the unit tests. It should not be used by @@ -48,8 +50,6 @@ class MethodChannelPathProvider extends PathProviderPlatform { return Directory(path); } - /// Path to the directory where application can store files that are persistent, - /// backed up, and not visible to the user, such as sqlite.db. Future getLibraryDirectory() async { if (!_platform.isIOS && !_platform.isMacOS) { throw UnsupportedError('Functionality only available on iOS/macOS'); @@ -83,10 +83,6 @@ class MethodChannelPathProvider extends PathProviderPlatform { return Directory(path); } - /// Paths to directories where application specific external cache data can be - /// stored. These paths typically reside on external storage like separate - /// partitions or SD cards. Phones may have multiple storage directories - /// available. Future> getExternalCacheDirectories() async { if (!_platform.isAndroid) { throw UnsupportedError('Functionality only available on Android'); @@ -97,12 +93,7 @@ class MethodChannelPathProvider extends PathProviderPlatform { return paths.map((String path) => Directory(path)).toList(); } - /// Paths to directories where application specific data can be stored. - /// These paths typically reside on external storage like separate partitions - /// or SD cards. Phones may have multiple storage directories available. Future> getExternalStorageDirectories({ - /// Optional parameter. See [StorageDirectory] for more informations on - /// how this type translates to Android storage directories. AndroidStorageDirectory type, }) async { if (!_platform.isAndroid) { @@ -116,8 +107,6 @@ class MethodChannelPathProvider extends PathProviderPlatform { return paths.map((String path) => Directory(path)).toList(); } - /// Path to the directory where downloaded files can be stored. - /// This is typically only relevant on desktop operating systems. Future getDownloadsDirectory() async { if (!_platform.isMacOS) { throw UnsupportedError('Functionality only available on macOS'); diff --git a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart index 72d574349ea8..60ed3ebdc392 100644 --- a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart +++ b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart @@ -53,6 +53,7 @@ void main() { await methodChannelPathProvider.getTemporaryDirectory(); expect(result.path, kTemporaryDirectory); }); + test('getApplicationSupportDirectory', () async { final Directory result = await methodChannelPathProvider.getApplicationSupportDirectory(); @@ -66,11 +67,13 @@ void main() { await methodChannelPathProvider.getLibraryDirectory(); expect(result.path, kLibraryDirectory); }); + test('getApplicationDocumentsDirectory', () async { final Directory result = await methodChannelPathProvider.getApplicationDocumentsDirectory(); expect(result.path, kApplicationDocumentsDirectory); }); + test('getExternalCacheDirectories', () async { methodChannelPathProvider.setMockPathProviderPlatform( FakePlatform(operatingSystem: 'android')); @@ -80,6 +83,7 @@ void main() { expect(result.length, 1); expect(result.first.path, kExternalCacheDirectories); }); + test('getExternalStorageDirectories', () async { methodChannelPathProvider.setMockPathProviderPlatform( FakePlatform(operatingSystem: 'android')); @@ -89,6 +93,7 @@ void main() { expect(result.length, 1); expect(result.first.path, kExternalStorageDirectories); }); + test('getDownloadsDirectory', () async { methodChannelPathProvider .setMockPathProviderPlatform(FakePlatform(operatingSystem: 'macos')); From 9085967a51cbfea911e9758d52881b1dc68d937a Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Tue, 25 Feb 2020 13:11:25 -0800 Subject: [PATCH 11/17] Space --- .../lib/src/method_channel_path_provider.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart index 29ae0073bffb..348a9d3964af 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart @@ -37,6 +37,7 @@ class MethodChannelPathProvider extends PathProviderPlatform { if (path == null) { return null; } + return Directory(path); } From 290e166435ac433a8fbc70559c8d8250407ad7f3 Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Tue, 25 Feb 2020 14:35:53 -0800 Subject: [PATCH 12/17] Rename apis to path and provide only the string from the platform --- .../lib/path_provider_platform_interface.dart | 35 +++++++++---------- .../lib/src/method_channel_path_provider.dart | 33 +++++++++-------- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart index 77bc39d88116..854866e31847 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:io' show Directory; import 'src/enums.dart'; import 'src/method_channel_path_provider.dart'; @@ -39,64 +38,62 @@ abstract class PathProviderPlatform extends PlatformInterface { /// Path to the temporary directory on the device that is not backed up and is /// suitable for storing caches of downloaded files. - Future getTemporaryDirectory() { - throw UnimplementedError( - 'getTemporaryDirectory() has not been implemented.'); + Future getTemporaryPath() { + throw UnimplementedError('getTemporaryPath() has not been implemented.'); } /// Path to a directory where the application may place application support /// files. - Future getApplicationSupportDirectory() { + Future getApplicationSupportPath() { throw UnimplementedError( - 'getApplicationSupportDirectory() has not been implemented.'); + 'getApplicationSupportPath() has not been implemented.'); } /// Path to the directory where application can store files that are persistent, /// backed up, and not visible to the user, such as sqlite.db. - Future getLibraryDirectory() { - throw UnimplementedError('getLibraryDirectory() has not been implemented.'); + Future getLibraryPath() { + throw UnimplementedError('getLibraryPath() has not been implemented.'); } /// Path to a directory where the application may place data that is /// user-generated, or that cannot otherwise be recreated by your application. - Future getApplicationDocumentsDirectory() { + Future getApplicationDocumentsPath() { throw UnimplementedError( - 'getApplicationDocumentsDirectory() has not been implemented.'); + 'getApplicationDocumentsPath() has not been implemented.'); } /// Path to a directory where the application may access top level storage. /// The current operating system should be determined before issuing this /// function call, as this functionality is only available on Android. - Future getExternalStorageDirectory() { + Future getExternalStoragePath() { throw UnimplementedError( - 'getExternalStorageDirectory() has not been implemented.'); + 'getExternalStoragePath() has not been implemented.'); } /// Paths to directories where application specific external cache data can be /// stored. These paths typically reside on external storage like separate /// partitions or SD cards. Phones may have multiple storage directories /// available. - Future> getExternalCacheDirectories() { + Future> getExternalCachePaths() { throw UnimplementedError( - 'getExternalCacheDirectories() has not been implemented.'); + 'getExternalCachePaths() has not been implemented.'); } /// Paths to directories where application specific data can be stored. /// These paths typically reside on external storage like separate partitions /// or SD cards. Phones may have multiple storage directories available. - Future> getExternalStorageDirectories({ + Future> getExternalStoragePaths({ /// Optional parameter. See [AndroidStorageDirectory] for more informations on /// how this type translates to Android storage directories. AndroidStorageDirectory type, }) { throw UnimplementedError( - 'getExternalStorageDirectories() has not been implemented.'); + 'getExternalStoragePaths() has not been implemented.'); } /// Path to the directory where downloaded files can be stored. /// This is typically only relevant on desktop operating systems. - Future getDownloadsDirectory() { - throw UnimplementedError( - 'getDownloadsDirectory() has not been implemented.'); + Future getDownloadsPath() { + throw UnimplementedError('getDownloadsPath() has not been implemented.'); } } diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart index 348a9d3964af..7eed2425074c 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:io' show Directory; import 'enums.dart'; @@ -31,27 +30,27 @@ class MethodChannelPathProvider extends PathProviderPlatform { _platform = platform; } - Future getTemporaryDirectory() async { + Future getTemporaryPath() async { final String path = await methodChannel.invokeMethod('getTemporaryDirectory'); if (path == null) { return null; } - return Directory(path); + return path; } - Future getApplicationSupportDirectory() async { + Future getApplicationSupportPath() async { final String path = await methodChannel .invokeMethod('getApplicationSupportDirectory'); if (path == null) { return null; } - return Directory(path); + return path; } - Future getLibraryDirectory() async { + Future getLibraryPath() async { if (!_platform.isIOS && !_platform.isMacOS) { throw UnsupportedError('Functionality only available on iOS/macOS'); } @@ -60,19 +59,19 @@ class MethodChannelPathProvider extends PathProviderPlatform { if (path == null) { return null; } - return Directory(path); + return path; } - Future getApplicationDocumentsDirectory() async { + Future getApplicationDocumentsPath() async { final String path = await methodChannel .invokeMethod('getApplicationDocumentsDirectory'); if (path == null) { return null; } - return Directory(path); + return path; } - Future getExternalStorageDirectory() async { + Future getExternalStoragePath() async { if (!_platform.isAndroid) { throw UnsupportedError('Functionality only available on Android'); } @@ -81,20 +80,20 @@ class MethodChannelPathProvider extends PathProviderPlatform { if (path == null) { return null; } - return Directory(path); + return path; } - Future> getExternalCacheDirectories() async { + Future> getExternalCachePaths() async { if (!_platform.isAndroid) { throw UnsupportedError('Functionality only available on Android'); } final List paths = await methodChannel .invokeListMethod('getExternalCacheDirectories'); - return paths.map((String path) => Directory(path)).toList(); + return paths.map((String path) => path).toList(); } - Future> getExternalStorageDirectories({ + Future> getExternalStoragePaths({ AndroidStorageDirectory type, }) async { if (!_platform.isAndroid) { @@ -105,10 +104,10 @@ class MethodChannelPathProvider extends PathProviderPlatform { {'type': type?.index}, ); - return paths.map((String path) => Directory(path)).toList(); + return paths.map((String path) => path).toList(); } - Future getDownloadsDirectory() async { + Future getDownloadsPath() async { if (!_platform.isMacOS) { throw UnsupportedError('Functionality only available on macOS'); } @@ -117,6 +116,6 @@ class MethodChannelPathProvider extends PathProviderPlatform { if (path == null) { return null; } - return Directory(path); + return path; } } From fcd271d796203692751e3c5b63c907848c6465ce Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Tue, 25 Feb 2020 14:54:13 -0800 Subject: [PATCH 13/17] Add test and remove null --- .../lib/src/method_channel_path_provider.dart | 43 ++-------- .../method_channel_path_provider_test.dart | 86 +++++++++---------- 2 files changed, 48 insertions(+), 81 deletions(-) diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart index 7eed2425074c..d41e4cd3fc8b 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart @@ -31,56 +31,30 @@ class MethodChannelPathProvider extends PathProviderPlatform { } Future getTemporaryPath() async { - final String path = - await methodChannel.invokeMethod('getTemporaryDirectory'); - if (path == null) { - return null; - } - - return path; + return methodChannel.invokeMethod('getTemporaryDirectory'); } Future getApplicationSupportPath() async { - final String path = await methodChannel - .invokeMethod('getApplicationSupportDirectory'); - if (path == null) { - return null; - } - - return path; + return methodChannel.invokeMethod('getApplicationSupportDirectory'); } Future getLibraryPath() async { if (!_platform.isIOS && !_platform.isMacOS) { throw UnsupportedError('Functionality only available on iOS/macOS'); } - final String path = - await methodChannel.invokeMethod('getLibraryDirectory'); - if (path == null) { - return null; - } - return path; + return methodChannel.invokeMethod('getLibraryDirectory'); } Future getApplicationDocumentsPath() async { - final String path = await methodChannel + return methodChannel .invokeMethod('getApplicationDocumentsDirectory'); - if (path == null) { - return null; - } - return path; } Future getExternalStoragePath() async { if (!_platform.isAndroid) { throw UnsupportedError('Functionality only available on Android'); } - final String path = - await methodChannel.invokeMethod('getStorageDirectory'); - if (path == null) { - return null; - } - return path; + return methodChannel.invokeMethod('getStorageDirectory'); } Future> getExternalCachePaths() async { @@ -111,11 +85,6 @@ class MethodChannelPathProvider extends PathProviderPlatform { if (!_platform.isMacOS) { throw UnsupportedError('Functionality only available on macOS'); } - final String path = - await methodChannel.invokeMethod('getDownloadsDirectory'); - if (path == null) { - return null; - } - return path; + return methodChannel.invokeMethod('getDownloadsDirectory'); } } diff --git a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart index 60ed3ebdc392..9dcde711d1b3 100644 --- a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart +++ b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:io' show Directory; - import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:path_provider_platform_interface/src/method_channel_path_provider.dart'; @@ -11,13 +9,13 @@ import 'package:platform/platform.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); - const String kTemporaryDirectory = 'temporaryDirectory'; - const String kApplicationSupportDirectory = 'applicationSupportDirectory'; - const String kLibraryDirectory = 'libraryDirectory'; - const String kApplicationDocumentsDirectory = 'applicationDocumentsDirectory'; - const String kExternalCacheDirectories = 'externalCacheDirectories'; - const String kExternalStorageDirectories = 'externalStorageDirectories'; - const String kDownloadsDirectory = 'downloadsDirectory'; + const String kTemporaryPath = 'temporaryPath'; + const String kApplicationSupportPath = 'applicationSupportPath'; + const String kLibraryPath = 'libraryPath'; + const String kApplicationDocumentsPath = 'applicationDocumentsPath'; + const String kExternalCachePaths = 'externalCachePaths'; + const String kExternalStoragePaths = 'externalStoragePaths'; + const String kDownloadsPath = 'downloadsPath'; group('$MethodChannelPathProvider', () { MethodChannelPathProvider methodChannelPathProvider; @@ -29,78 +27,78 @@ void main() { .setMockMethodCallHandler((MethodCall methodCall) async { switch (methodCall.method) { case 'getTemporaryDirectory': - return kTemporaryDirectory; + return kTemporaryPath; case 'getApplicationSupportDirectory': - return kApplicationSupportDirectory; + return kApplicationSupportPath; case 'getLibraryDirectory': - return kLibraryDirectory; + return kLibraryPath; case 'getApplicationDocumentsDirectory': - return kApplicationDocumentsDirectory; + return kApplicationDocumentsPath; case 'getExternalStorageDirectories': - return [kExternalStorageDirectories]; + return [kExternalStoragePaths]; case 'getExternalCacheDirectories': - return [kExternalCacheDirectories]; + return [kExternalCachePaths]; case 'getDownloadsDirectory': - return kDownloadsDirectory; + return kDownloadsPath; default: return null; } }); }); - test('getTemporaryDirectory', () async { - final Directory result = - await methodChannelPathProvider.getTemporaryDirectory(); - expect(result.path, kTemporaryDirectory); + test('getTemporaryPath', () async { + final String result = + await methodChannelPathProvider.getTemporaryPath(); + expect(result, kTemporaryPath); }); - test('getApplicationSupportDirectory', () async { - final Directory result = - await methodChannelPathProvider.getApplicationSupportDirectory(); - expect(result.path, kApplicationSupportDirectory); + test('getApplicationSupportPath', () async { + final String result = + await methodChannelPathProvider.getApplicationSupportPath(); + expect(result, kApplicationSupportPath); }); - test('getLibraryDirectory', () async { + test('getLibraryPath', () async { methodChannelPathProvider .setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); - final Directory result = - await methodChannelPathProvider.getLibraryDirectory(); - expect(result.path, kLibraryDirectory); + final String result = + await methodChannelPathProvider.getLibraryPath(); + expect(result, kLibraryPath); }); - test('getApplicationDocumentsDirectory', () async { - final Directory result = - await methodChannelPathProvider.getApplicationDocumentsDirectory(); - expect(result.path, kApplicationDocumentsDirectory); + test('getApplicationDocumentsPath', () async { + final String result = + await methodChannelPathProvider.getApplicationDocumentsPath(); + expect(result, kApplicationDocumentsPath); }); - test('getExternalCacheDirectories', () async { + test('getExternalCachePaths', () async { methodChannelPathProvider.setMockPathProviderPlatform( FakePlatform(operatingSystem: 'android')); - final List result = - await methodChannelPathProvider.getExternalCacheDirectories(); + final List result = + await methodChannelPathProvider.getExternalCachePaths(); expect(result.length, 1); - expect(result.first.path, kExternalCacheDirectories); + expect(result.first, kExternalCachePaths); }); - test('getExternalStorageDirectories', () async { + test('getExternalStoragePaths', () async { methodChannelPathProvider.setMockPathProviderPlatform( FakePlatform(operatingSystem: 'android')); - final List result = - await methodChannelPathProvider.getExternalStorageDirectories(); + final List result = + await methodChannelPathProvider.getExternalStoragePaths(); expect(result.length, 1); - expect(result.first.path, kExternalStorageDirectories); + expect(result.first, kExternalStoragePaths); }); - test('getDownloadsDirectory', () async { + test('getDownloadsPath', () async { methodChannelPathProvider .setMockPathProviderPlatform(FakePlatform(operatingSystem: 'macos')); - final Directory result = - await methodChannelPathProvider.getDownloadsDirectory(); + final String result = + await methodChannelPathProvider.getDownloadsPath(); - expect(result.path, kDownloadsDirectory); + expect(result, kDownloadsPath); }); }); } From 0d7dbbd3e5898bf97586ea6a69715d58024ccb5c Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Tue, 25 Feb 2020 15:06:52 -0800 Subject: [PATCH 14/17] Format --- .../test/method_channel_path_provider_test.dart | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart index 9dcde711d1b3..671bb8118b7f 100644 --- a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart +++ b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart @@ -47,8 +47,7 @@ void main() { }); test('getTemporaryPath', () async { - final String result = - await methodChannelPathProvider.getTemporaryPath(); + final String result = await methodChannelPathProvider.getTemporaryPath(); expect(result, kTemporaryPath); }); @@ -61,8 +60,7 @@ void main() { test('getLibraryPath', () async { methodChannelPathProvider .setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); - final String result = - await methodChannelPathProvider.getLibraryPath(); + final String result = await methodChannelPathProvider.getLibraryPath(); expect(result, kLibraryPath); }); @@ -95,8 +93,7 @@ void main() { test('getDownloadsPath', () async { methodChannelPathProvider .setMockPathProviderPlatform(FakePlatform(operatingSystem: 'macos')); - final String result = - await methodChannelPathProvider.getDownloadsPath(); + final String result = await methodChannelPathProvider.getDownloadsPath(); expect(result, kDownloadsPath); }); From 8d9219a2cce2150ef09b3bf1b9da9c26288cdfab Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Tue, 25 Feb 2020 15:20:51 -0800 Subject: [PATCH 15/17] Add export --- .../lib/path_provider_platform_interface.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart index 854866e31847..72aadf35b3e8 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart @@ -9,6 +9,8 @@ import 'src/method_channel_path_provider.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +export 'src/enums.dart'; + /// The interface that implementations of path_provider must implement. /// /// Platform implementations should extend this class rather than implement it as `PathProvider` From 689ac160601793a2ae9ed508107e8ebcdc229b9c Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Tue, 25 Feb 2020 16:39:11 -0800 Subject: [PATCH 16/17] Improve tests --- .../method_channel_path_provider_test.dart | 147 +++++++++++++++--- 1 file changed, 125 insertions(+), 22 deletions(-) diff --git a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart index 671bb8118b7f..c21acdb140b6 100644 --- a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart +++ b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart @@ -4,6 +4,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:path_provider_platform_interface/src/enums.dart'; import 'package:path_provider_platform_interface/src/method_channel_path_provider.dart'; import 'package:platform/platform.dart'; @@ -19,12 +20,14 @@ void main() { group('$MethodChannelPathProvider', () { MethodChannelPathProvider methodChannelPathProvider; + final List log = []; setUp(() async { methodChannelPathProvider = MethodChannelPathProvider(); methodChannelPathProvider.methodChannel .setMockMethodCallHandler((MethodCall methodCall) async { + log.add(methodCall); switch (methodCall.method) { case 'getTemporaryDirectory': return kTemporaryPath; @@ -46,56 +49,156 @@ void main() { }); }); + setUp(() { + methodChannelPathProvider.setMockPathProviderPlatform( + FakePlatform(operatingSystem: 'android')); + }); + + tearDown(() { + log.clear(); + }); + test('getTemporaryPath', () async { - final String result = await methodChannelPathProvider.getTemporaryPath(); - expect(result, kTemporaryPath); + final String path = await methodChannelPathProvider.getTemporaryPath(); + expect( + log, + [isMethodCall('getTemporaryDirectory', arguments: null)], + ); + expect(path, kTemporaryPath); }); test('getApplicationSupportPath', () async { - final String result = + final String path = await methodChannelPathProvider.getApplicationSupportPath(); - expect(result, kApplicationSupportPath); + expect( + log, + [ + isMethodCall('getApplicationSupportDirectory', arguments: null) + ], + ); + expect(path, kApplicationSupportPath); + }); + + test('getLibraryPath android fails', () async { + try { + await methodChannelPathProvider.getLibraryPath(); + fail('should throw UnsupportedError'); + } catch (e) { + expect(e, isUnsupportedError); + } }); - test('getLibraryPath', () async { + test('getLibraryPath iOS succeeds', () async { methodChannelPathProvider .setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); - final String result = await methodChannelPathProvider.getLibraryPath(); - expect(result, kLibraryPath); + + final String path = await methodChannelPathProvider.getLibraryPath(); + expect( + log, + [isMethodCall('getLibraryDirectory', arguments: null)], + ); + expect(path, kLibraryPath); + }); + + test('getLibraryPath macOS succeeds', () async { + methodChannelPathProvider + .setMockPathProviderPlatform(FakePlatform(operatingSystem: 'macos')); + + final String path = await methodChannelPathProvider.getLibraryPath(); + expect( + log, + [isMethodCall('getLibraryDirectory', arguments: null)], + ); + expect(path, kLibraryPath); }); test('getApplicationDocumentsPath', () async { - final String result = + final String path = await methodChannelPathProvider.getApplicationDocumentsPath(); - expect(result, kApplicationDocumentsPath); + expect( + log, + [ + isMethodCall('getApplicationDocumentsDirectory', arguments: null) + ], + ); + expect(path, kApplicationDocumentsPath); }); - test('getExternalCachePaths', () async { - methodChannelPathProvider.setMockPathProviderPlatform( - FakePlatform(operatingSystem: 'android')); + test('getExternalCachePaths android succeeds', () async { final List result = await methodChannelPathProvider.getExternalCachePaths(); - + expect( + log, + [isMethodCall('getExternalCacheDirectories', arguments: null)], + ); expect(result.length, 1); expect(result.first, kExternalCachePaths); }); - test('getExternalStoragePaths', () async { - methodChannelPathProvider.setMockPathProviderPlatform( - FakePlatform(operatingSystem: 'android')); - final List result = - await methodChannelPathProvider.getExternalStoragePaths(); + test('getExternalCachePaths non-android fails', () async { + methodChannelPathProvider + .setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); - expect(result.length, 1); - expect(result.first, kExternalStoragePaths); + try { + await methodChannelPathProvider.getExternalCachePaths(); + fail('should throw UnsupportedError'); + } catch (e) { + expect(e, isUnsupportedError); + } }); - test('getDownloadsPath', () async { + for (AndroidStorageDirectory type + in AndroidStorageDirectory.values + [null]) { + test('getExternalStoragePaths (type: $type) android succeeds', () async { + final List result = + await methodChannelPathProvider.getExternalStoragePaths(type: type); + expect( + log, + [ + isMethodCall( + 'getExternalStorageDirectories', + arguments: {'type': type?.index}, + ) + ], + ); + + expect(result.length, 1); + expect(result.first, kExternalStoragePaths); + }); + + test('getExternalStoragePaths (type: $type) non-android fails', () async { + methodChannelPathProvider + .setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); + + try { + await methodChannelPathProvider.getExternalStoragePaths(); + fail('should throw UnsupportedError'); + } catch (e) { + expect(e, isUnsupportedError); + } + }); + } // end of for-loop + + test('getDownloadsPath macos succeeds', () async { methodChannelPathProvider .setMockPathProviderPlatform(FakePlatform(operatingSystem: 'macos')); final String result = await methodChannelPathProvider.getDownloadsPath(); - + expect( + log, + [isMethodCall('getDownloadsDirectory', arguments: null)], + ); expect(result, kDownloadsPath); }); + + test('getDownloadsPath non-macos fails', () async { + methodChannelPathProvider.setMockPathProviderPlatform( + FakePlatform(operatingSystem: 'android')); + try { + await methodChannelPathProvider.getDownloadsPath(); + fail('should throw UnsupportedError'); + } catch (e) { + expect(e, isUnsupportedError); + } + }); }); } From 7f7d351d24948c012c287e986f385688aef4506a Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Tue, 25 Feb 2020 20:35:03 -0800 Subject: [PATCH 17/17] Remove asyncs --- .../lib/src/method_channel_path_provider.dart | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart index d41e4cd3fc8b..acac9d5fe7af 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart @@ -30,41 +30,39 @@ class MethodChannelPathProvider extends PathProviderPlatform { _platform = platform; } - Future getTemporaryPath() async { + Future getTemporaryPath() { return methodChannel.invokeMethod('getTemporaryDirectory'); } - Future getApplicationSupportPath() async { + Future getApplicationSupportPath() { return methodChannel.invokeMethod('getApplicationSupportDirectory'); } - Future getLibraryPath() async { + Future getLibraryPath() { if (!_platform.isIOS && !_platform.isMacOS) { throw UnsupportedError('Functionality only available on iOS/macOS'); } return methodChannel.invokeMethod('getLibraryDirectory'); } - Future getApplicationDocumentsPath() async { + Future getApplicationDocumentsPath() { return methodChannel .invokeMethod('getApplicationDocumentsDirectory'); } - Future getExternalStoragePath() async { + Future getExternalStoragePath() { if (!_platform.isAndroid) { throw UnsupportedError('Functionality only available on Android'); } return methodChannel.invokeMethod('getStorageDirectory'); } - Future> getExternalCachePaths() async { + Future> getExternalCachePaths() { if (!_platform.isAndroid) { throw UnsupportedError('Functionality only available on Android'); } - final List paths = await methodChannel + return methodChannel .invokeListMethod('getExternalCacheDirectories'); - - return paths.map((String path) => path).toList(); } Future> getExternalStoragePaths({ @@ -73,15 +71,13 @@ class MethodChannelPathProvider extends PathProviderPlatform { if (!_platform.isAndroid) { throw UnsupportedError('Functionality only available on Android'); } - final List paths = await methodChannel.invokeListMethod( + return methodChannel.invokeListMethod( 'getExternalStorageDirectories', {'type': type?.index}, ); - - return paths.map((String path) => path).toList(); } - Future getDownloadsPath() async { + Future getDownloadsPath() { if (!_platform.isMacOS) { throw UnsupportedError('Functionality only available on macOS'); }