diff --git a/packages/path_provider/path_provider/CHANGELOG.md b/packages/path_provider/path_provider/CHANGELOG.md index 439c0c52cdda..3540e20e5141 100644 --- a/packages/path_provider/path_provider/CHANGELOG.md +++ b/packages/path_provider/path_provider/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.3 + +* Use `path_provider_platform_interface` in core plugin. + ## 1.6.2 * Move package contents into `path_provider` for platform federation. diff --git a/packages/path_provider/path_provider/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/packages/path_provider/path_provider/example/macos/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a16ed0f..000000000000 --- a/packages/path_provider/path_provider/example/macos/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/packages/path_provider/path_provider/lib/path_provider.dart b/packages/path_provider/path_provider/lib/path_provider.dart index b27cc4bc3fcb..a7643264d52a 100644 --- a/packages/path_provider/path_provider/lib/path_provider.dart +++ b/packages/path_provider/path_provider/lib/path_provider.dart @@ -5,21 +5,12 @@ import 'dart:async'; import 'dart:io' show Directory; -import 'package:flutter/services.dart'; -import 'package:meta/meta.dart'; -import 'package:platform/platform.dart'; +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; -const MethodChannel _channel = - MethodChannel('plugins.flutter.io/path_provider'); +export 'package:path_provider_platform_interface/path_provider_platform_interface.dart' + show StorageDirectory; -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; -} +PathProviderPlatform get _platform => PathProviderPlatform.instance; /// Path to the temporary directory on the device that is not backed up and is /// suitable for storing caches of downloaded files. @@ -33,8 +24,7 @@ void setMockPathProviderPlatform(Platform platform) { /// /// On Android, this uses the `getCacheDir` API on the context. Future getTemporaryDirectory() async { - final String path = - await _channel.invokeMethod('getTemporaryDirectory'); + final String path = await _platform.getTemporaryPath(); if (path == null) { return null; } @@ -52,8 +42,7 @@ Future getTemporaryDirectory() async { /// /// On Android, this function uses the `getFilesDir` API on the context. Future getApplicationSupportDirectory() async { - final String path = - await _channel.invokeMethod('getApplicationSupportDirectory'); + final String path = await _platform.getApplicationSupportPath(); if (path == null) { return null; } @@ -67,11 +56,7 @@ Future getApplicationSupportDirectory() async { /// On Android, this function throws an [UnsupportedError] as no equivalent /// path exists. Future getLibraryDirectory() async { - if (_platform.isAndroid) { - throw UnsupportedError('Functionality not available on Android'); - } - final String path = - await _channel.invokeMethod('getLibraryDirectory'); + final String path = await _platform.getLibraryPath(); if (path == null) { return null; } @@ -88,8 +73,7 @@ Future getLibraryDirectory() async { /// using [getExternalStorageDirectory] instead if data is intended to be visible /// to the user. Future getApplicationDocumentsDirectory() async { - final String path = - await _channel.invokeMethod('getApplicationDocumentsDirectory'); + final String path = await _platform.getApplicationDocumentsPath(); if (path == null) { return null; } @@ -105,11 +89,7 @@ Future getApplicationDocumentsDirectory() async { /// /// On Android this uses the `getExternalFilesDir(null)`. Future getExternalStorageDirectory() async { - if (_platform.isIOS) { - throw UnsupportedError('Functionality not available on iOS'); - } - final String path = - await _channel.invokeMethod('getStorageDirectory'); + final String path = await _platform.getExternalStoragePath(); if (path == null) { return null; } @@ -130,65 +110,11 @@ Future getExternalStorageDirectory() async { /// On Android this returns Context.getExternalCacheDirs() or /// Context.getExternalCacheDir() on API levels below 19. Future> getExternalCacheDirectories() async { - if (_platform.isIOS) { - throw UnsupportedError('Functionality not available on iOS'); - } - final List paths = - await _channel.invokeListMethod('getExternalCacheDirectories'); + final List paths = await _platform.getExternalCachePaths(); return paths.map((String path) => Directory(path)).toList(); } -/// Corresponds to constants defined in Androids `android.os.Environment` class. -/// -/// https://developer.android.com/reference/android/os/Environment.html#fields_1 -enum StorageDirectory { - /// 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, -} - /// 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. @@ -206,13 +132,8 @@ Future> getExternalStorageDirectories({ /// how this type translates to Android storage directories. StorageDirectory type, }) async { - if (_platform.isIOS) { - throw UnsupportedError('Functionality not available on iOS'); - } - final List paths = await _channel.invokeListMethod( - 'getExternalStorageDirectories', - {'type': type?.index}, - ); + final List paths = + await _platform.getExternalStoragePaths(type: type); return paths.map((String path) => Directory(path)).toList(); } @@ -223,14 +144,7 @@ Future> getExternalStorageDirectories({ /// On Android and on iOS, this function throws an [UnsupportedError] as no equivalent /// path exists. Future getDownloadsDirectory() async { - if (_platform.isAndroid) { - throw UnsupportedError('Functionality not available on Android'); - } - if (_platform.isIOS) { - throw UnsupportedError('Functionality not available on iOS'); - } - final String path = - await _channel.invokeMethod('getDownloadsDirectory'); + final String path = await _platform.getDownloadsPath(); if (path == null) { return null; } diff --git a/packages/path_provider/path_provider/pubspec.yaml b/packages/path_provider/path_provider/pubspec.yaml index df26c5e06899..c20d83b32542 100644 --- a/packages/path_provider/path_provider/pubspec.yaml +++ b/packages/path_provider/path_provider/pubspec.yaml @@ -2,7 +2,7 @@ name: path_provider description: Flutter plugin for getting commonly used locations on the Android & iOS file systems, such as the temp and app data directories. homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider -version: 1.6.2 +version: 1.6.3 flutter: plugin: @@ -16,8 +16,7 @@ flutter: dependencies: flutter: sdk: flutter - platform: ^2.0.0 - meta: ^1.0.5 + path_provider_platform_interface: ^1.0.1 dev_dependencies: e2e: ^0.2.1 @@ -28,6 +27,8 @@ dev_dependencies: test: any uuid: "^1.0.0" pedantic: ^1.8.0 + mockito: ^4.1.1 + plugin_platform_interface: ^1.0.0 environment: sdk: ">=2.0.0-dev.28.0 <3.0.0" diff --git a/packages/path_provider/path_provider/test/path_provider_test.dart b/packages/path_provider/path_provider/test/path_provider_test.dart index 5b875e3bc51e..eb17178b9975 100644 --- a/packages/path_provider/path_provider/test/path_provider_test.dart +++ b/packages/path_provider/path_provider/test/path_provider_test.dart @@ -2,236 +2,109 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:io'; +import 'dart:io' show Directory; +import 'dart:async'; -import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:platform/platform.dart'; +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - - const MethodChannel channel = - MethodChannel('plugins.flutter.io/path_provider'); - final List log = []; - dynamic response; - - channel.setMockMethodCallHandler((MethodCall methodCall) async { - log.add(methodCall); - return response; - }); - - setUp(() { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'android')); - }); - - tearDown(() { - log.clear(); - }); - - test('getTemporaryDirectory test', () async { - response = null; - final Directory directory = await getTemporaryDirectory(); - expect( - log, - [isMethodCall('getTemporaryDirectory', arguments: null)], - ); - expect(directory, isNull); - }); - - test('getApplicationSupportDirectory test', () async { - response = null; - final Directory directory = await getApplicationSupportDirectory(); - expect( - log, - [ - isMethodCall('getApplicationSupportDirectory', arguments: null) - ], - ); - expect(directory, isNull); - }); - - test('getApplicationDocumentsDirectory test', () async { - response = null; - final Directory directory = await getApplicationDocumentsDirectory(); - expect( - log, - [ - isMethodCall('getApplicationDocumentsDirectory', arguments: null) - ], - ); - expect(directory, isNull); - }); - - test('getApplicationSupportDirectory test', () async { - response = null; - final Directory directory = await getApplicationSupportDirectory(); - expect( - log, - [ - isMethodCall('getApplicationSupportDirectory', arguments: null) - ], - ); - expect(directory, isNull); - }); +const String kTemporaryPath = 'temporaryPath'; +const String kApplicationSupportPath = 'applicationSupportPath'; +const String kDownloadsPath = 'downloadsPath'; +const String kLibraryPath = 'libraryPath'; +const String kApplicationDocumentsPath = 'applicationDocumentsPath'; +const String kExternalCachePath = 'externalCachePath'; +const String kExternalStoragePath = 'externalStoragePath'; - test('getExternalStorageDirectory test', () async { - response = null; - final Directory directory = await getExternalStorageDirectory(); - expect( - log, - [isMethodCall('getStorageDirectory', arguments: null)], - ); - expect(directory, isNull); - }); - - test('getLibraryDirectory Android test', () async { - try { - await getLibraryDirectory(); - fail('should throw UnsupportedError'); - } catch (e) { - expect(e, isUnsupportedError); - } - }); - test('getLibraryDirectory iOS test', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); - - final Directory directory = await getLibraryDirectory(); - expect( - log, - [isMethodCall('getLibraryDirectory', arguments: null)], - ); - expect(directory, isNull); - }); - - test('getExternalStorageDirectory iOS test', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); +void main() { + group('PathProvider', () { + TestWidgetsFlutterBinding.ensureInitialized(); - try { - await getExternalStorageDirectory(); - fail('should throw UnsupportedError'); - } catch (e) { - expect(e, isUnsupportedError); - } - }); + setUp(() async { + PathProviderPlatform.instance = MockPathProviderPlatform(); + }); - test('getExternalCacheDirectories test', () async { - response = []; - final List directories = await getExternalCacheDirectories(); - expect( - log, - [isMethodCall('getExternalCacheDirectories', arguments: null)], - ); - expect(directories, []); - }); + test('getTemporaryDirectory', () async { + Directory result = await getTemporaryDirectory(); + expect(result.path, kTemporaryPath); + }); - test('getExternalCacheDirectories iOS test', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); + test('getApplicationSupportDirectory', () async { + Directory result = await getApplicationSupportDirectory(); + expect(result.path, kApplicationSupportPath); + }); - try { - await getExternalCacheDirectories(); - fail('should throw UnsupportedError'); - } catch (e) { - expect(e, isUnsupportedError); - } - }); + test('getLibraryDirectory', () async { + Directory result = await getLibraryDirectory(); + expect(result.path, kLibraryPath); + }); - for (StorageDirectory type - in StorageDirectory.values + [null]) { - test('getExternalStorageDirectories test (type: $type)', () async { - response = []; - final List directories = - await getExternalStorageDirectories(type: type); - expect( - log, - [ - isMethodCall( - 'getExternalStorageDirectories', - arguments: {'type': type?.index}, - ) - ], - ); - expect(directories, []); + test('getApplicationDocumentsDirectory', () async { + Directory result = await getApplicationDocumentsDirectory(); + expect(result.path, kApplicationDocumentsPath); }); - } - test('getExternalStorageDirectories iOS test', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); + test('getExternalStorageDirectory', () async { + Directory result = await getExternalStorageDirectory(); + expect(result.path, kExternalStoragePath); + }); - try { - await getExternalStorageDirectories(type: StorageDirectory.music); - fail('should throw UnsupportedError'); - } catch (e) { - expect(e, isUnsupportedError); - } - }); + test('getExternalCacheDirectories', () async { + List result = await getExternalCacheDirectories(); + expect(result.length, 1); + expect(result.first.path, kExternalCachePath); + }); - test('TemporaryDirectory path test', () async { - final String fakePath = "/foo/bar/baz"; - response = fakePath; - final Directory directory = await getTemporaryDirectory(); - expect(directory.path, equals(fakePath)); - }); + test('getExternalStorageDirectories', () async { + List result = await getExternalStorageDirectories(); + expect(result.length, 1); + expect(result.first.path, kExternalStoragePath); + }); - test('ApplicationSupportDirectory path test', () async { - final String fakePath = "/foo/bar/baz"; - response = fakePath; - final Directory directory = await getApplicationSupportDirectory(); - expect(directory.path, equals(fakePath)); + test('getDownloadsDirectory', () async { + Directory result = await getDownloadsDirectory(); + expect(result.path, kDownloadsPath); + }); }); +} - test('ApplicationDocumentsDirectory path test', () async { - final String fakePath = "/foo/bar/baz"; - response = fakePath; - final Directory directory = await getApplicationDocumentsDirectory(); - expect(directory.path, equals(fakePath)); - }); +class MockPathProviderPlatform extends Mock + with MockPlatformInterfaceMixin + implements PathProviderPlatform { + Future getTemporaryPath() async { + return kTemporaryPath; + } - test('ApplicationSupportDirectory path test', () async { - final String fakePath = "/foo/bar/baz"; - response = fakePath; - final Directory directory = await getApplicationSupportDirectory(); - expect(directory.path, equals(fakePath)); - }); + Future getApplicationSupportPath() async { + return kApplicationSupportPath; + } - test('ApplicationLibraryDirectory path test', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); + Future getLibraryPath() async { + return kLibraryPath; + } - final String fakePath = "/foo/bar/baz"; - response = fakePath; - final Directory directory = await getLibraryDirectory(); - expect(directory.path, equals(fakePath)); - }); + Future getApplicationDocumentsPath() async { + return kApplicationDocumentsPath; + } - test('ExternalStorageDirectory path test', () async { - final String fakePath = "/foo/bar/baz"; - response = fakePath; - final Directory directory = await getExternalStorageDirectory(); - expect(directory.path, equals(fakePath)); - }); + Future getExternalStoragePath() async { + return kExternalStoragePath; + } - test('ExternalCacheDirectories path test', () async { - final List paths = ["/foo/bar/baz", "/foo/bar/baz2"]; - response = paths; - final List directories = await getExternalCacheDirectories(); - expect(directories.map((Directory d) => d.path).toList(), equals(paths)); - }); + Future> getExternalCachePaths() async { + return [kExternalCachePath]; + } - test('ExternalStorageDirectories path test', () async { - final List paths = ["/foo/bar/baz", "/foo/bar/baz2"]; - response = paths; - final List directories = await getExternalStorageDirectories( - type: StorageDirectory.music, - ); - expect(directories.map((Directory d) => d.path).toList(), equals(paths)); - }); + Future> getExternalStoragePaths({ + StorageDirectory type, + }) async { + return [kExternalStoragePath]; + } - test('DownloadsDirectory path macos test', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'macos')); - final String fakePath = "/foo/bar/baz"; - response = fakePath; - final Directory directory = await getDownloadsDirectory(); - expect(directory.path, equals(fakePath)); - }); + Future getDownloadsPath() async { + return kDownloadsPath; + } }