diff --git a/packages/path_provider/path_provider_android/CHANGELOG.md b/packages/path_provider/path_provider_android/CHANGELOG.md index 628bd442c42f..f9d3543a92d4 100644 --- a/packages/path_provider/path_provider_android/CHANGELOG.md +++ b/packages/path_provider/path_provider_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.10 + +* Switches to a package-internal implementation of the platform interface. + ## 2.0.9 * Updates Android compileSdkVersion to 31. diff --git a/packages/path_provider/path_provider_android/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java b/packages/path_provider/path_provider_android/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java index 3ff2416527d0..278ff58b59dc 100644 --- a/packages/path_provider/path_provider_android/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java +++ b/packages/path_provider/path_provider_android/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java @@ -153,7 +153,7 @@ public void getApplicationSupportDirectory(@NonNull Result result) { public PathProviderPlugin() {} private void setup(BinaryMessenger messenger, Context context) { - String channelName = "plugins.flutter.io/path_provider"; + String channelName = "plugins.flutter.io/path_provider_android"; // TODO(gaaclarke): Remove reflection guard when https://github.com/flutter/engine/pull/29147 // becomes available on the stable branch. try { diff --git a/packages/path_provider/path_provider_android/lib/path_provider_android.dart b/packages/path_provider/path_provider_android/lib/path_provider_android.dart new file mode 100644 index 000000000000..b0f3808d2859 --- /dev/null +++ b/packages/path_provider/path_provider_android/lib/path_provider_android.dart @@ -0,0 +1,67 @@ +// Copyright 2013 The Flutter 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 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; + +/// The Android implementation of [PathProviderPlatform]. +class PathProviderAndroid extends PathProviderPlatform { + /// The method channel used to interact with the native platform. + @visibleForTesting + MethodChannel methodChannel = + const MethodChannel('plugins.flutter.io/path_provider_android'); + + /// Registers this class as the default instance of [PathProviderPlatform]. + static void registerWith() { + PathProviderPlatform.instance = PathProviderAndroid(); + } + + @override + Future getTemporaryPath() { + return methodChannel.invokeMethod('getTemporaryDirectory'); + } + + @override + Future getApplicationSupportPath() { + return methodChannel.invokeMethod('getApplicationSupportDirectory'); + } + + @override + Future getLibraryPath() { + throw UnsupportedError('getLibraryPath is not supported on Android'); + } + + @override + Future getApplicationDocumentsPath() { + return methodChannel + .invokeMethod('getApplicationDocumentsDirectory'); + } + + @override + Future getExternalStoragePath() { + return methodChannel.invokeMethod('getStorageDirectory'); + } + + @override + Future?> getExternalCachePaths() { + return methodChannel + .invokeListMethod('getExternalCacheDirectories'); + } + + @override + Future?> getExternalStoragePaths({ + StorageDirectory? type, + }) async { + return methodChannel.invokeListMethod( + 'getExternalStorageDirectories', + {'type': type?.index}, + ); + } + + @override + Future getDownloadsPath() { + throw UnsupportedError('getDownloadsPath is not supported on Android'); + } +} diff --git a/packages/path_provider/path_provider_android/pubspec.yaml b/packages/path_provider/path_provider_android/pubspec.yaml index 09b26a5efedb..5664ebf7944c 100644 --- a/packages/path_provider/path_provider_android/pubspec.yaml +++ b/packages/path_provider/path_provider_android/pubspec.yaml @@ -2,7 +2,7 @@ name: path_provider_android description: Android implementation of the path_provider plugin. repository: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+path_provider%22 -version: 2.0.9 +version: 2.0.10 environment: sdk: ">=2.14.0 <3.0.0" @@ -15,11 +15,12 @@ flutter: android: package: io.flutter.plugins.pathprovider pluginClass: PathProviderPlugin + dartPluginClass: PathProviderAndroid dependencies: flutter: sdk: flutter - path_provider_platform_interface: ^2.0.0 + path_provider_platform_interface: ^2.0.1 dev_dependencies: flutter_driver: diff --git a/packages/path_provider/path_provider_android/test/path_provider_android_test.dart b/packages/path_provider/path_provider_android/test/path_provider_android_test.dart new file mode 100644 index 000000000000..d2f9682bf6d7 --- /dev/null +++ b/packages/path_provider/path_provider_android/test/path_provider_android_test.dart @@ -0,0 +1,136 @@ +// Copyright 2013 The Flutter 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 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:path_provider_android/path_provider_android.dart'; +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + 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('PathProviderAndroid', () { + late PathProviderAndroid pathProvider; + final List log = []; + + setUp(() async { + pathProvider = PathProviderAndroid(); + TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger + .setMockMethodCallHandler(pathProvider.methodChannel, + (MethodCall methodCall) async { + log.add(methodCall); + switch (methodCall.method) { + case 'getTemporaryDirectory': + return kTemporaryPath; + case 'getApplicationSupportDirectory': + return kApplicationSupportPath; + case 'getLibraryDirectory': + return kLibraryPath; + case 'getApplicationDocumentsDirectory': + return kApplicationDocumentsPath; + case 'getExternalStorageDirectories': + return [kExternalStoragePaths]; + case 'getExternalCacheDirectories': + return [kExternalCachePaths]; + case 'getDownloadsDirectory': + return kDownloadsPath; + default: + return null; + } + }); + }); + + tearDown(() { + log.clear(); + }); + + test('getTemporaryPath', () async { + final String? path = await pathProvider.getTemporaryPath(); + expect( + log, + [isMethodCall('getTemporaryDirectory', arguments: null)], + ); + expect(path, kTemporaryPath); + }); + + test('getApplicationSupportPath', () async { + final String? path = await pathProvider.getApplicationSupportPath(); + expect( + log, + [ + isMethodCall('getApplicationSupportDirectory', arguments: null) + ], + ); + expect(path, kApplicationSupportPath); + }); + + test('getLibraryPath fails', () async { + try { + await pathProvider.getLibraryPath(); + fail('should throw UnsupportedError'); + } catch (e) { + expect(e, isUnsupportedError); + } + }); + + test('getApplicationDocumentsPath', () async { + final String? path = await pathProvider.getApplicationDocumentsPath(); + expect( + log, + [ + isMethodCall('getApplicationDocumentsDirectory', arguments: null) + ], + ); + expect(path, kApplicationDocumentsPath); + }); + + test('getExternalCachePaths succeeds', () async { + final List? result = await pathProvider.getExternalCachePaths(); + expect( + log, + [isMethodCall('getExternalCacheDirectories', arguments: null)], + ); + expect(result!.length, 1); + expect(result.first, kExternalCachePaths); + }); + + for (final StorageDirectory? type in [ + null, + ...StorageDirectory.values + ]) { + test('getExternalStoragePaths (type: $type) android succeeds', () async { + final List? result = + await pathProvider.getExternalStoragePaths(type: type); + expect( + log, + [ + isMethodCall( + 'getExternalStorageDirectories', + arguments: {'type': type?.index}, + ) + ], + ); + + expect(result!.length, 1); + expect(result.first, kExternalStoragePaths); + }); + } // end of for-loop + + test('getDownloadsPath fails', () async { + try { + await pathProvider.getDownloadsPath(); + fail('should throw UnsupportedError'); + } catch (e) { + expect(e, isUnsupportedError); + } + }); + }); +}