path_provider: update for official packages/path_provider 2.2.0 (#68)

Signed-off-by: Hidenori Matsubayashi <Hidenori.Matsubayashi@gmail.com>
This commit is contained in:
Hidenori Matsubayashi
2023-08-06 00:04:11 +00:00
committed by GitHub
parent 1f6a66c618
commit a34cc52248
12 changed files with 277 additions and 69 deletions

View File

@ -17,7 +17,7 @@ The plugins for elinux are basically designed to be API compatible with the offi
| ------------------ | ---------------- |
| [video_player_elinux](packages/video_player) | [video_player](https://github.com/flutter/plugins/tree/master/packages/video_player) |
| [camera_elinux](packages/camera) | [camera](https://github.com/flutter/plugins/tree/master/packages/camera) |
| [path_provider_elinux](packages/path_provider) | [path_provider](https://github.com/flutter/plugins/tree/master/packages/path_provider) |
| [path_provider_elinux](packages/path_provider) | [path_provider](https://github.com/flutter/packages/tree/main/packages/path_provider) |
| [shared_preferences_elinux](packages/shared_preferences) | [shared_preferences](https://github.com/flutter/plugins/tree/master/packages/shared_preferences) |
| [joystick](packages/joystick) | - |

View File

@ -1,3 +1,6 @@
## 2.2.0
* Update for path_provider 2.2.0
## 1.0.2
* Update for flutter 3.3.0 release

View File

@ -36,6 +36,12 @@ void main() {
final String? result = await provider.getApplicationSupportPath();
_verifySampleFile(result, 'applicationSupport');
});
testWidgets('getApplicationCacheDirectory', (WidgetTester tester) async {
final PathProviderELinux provider = PathProviderELinux();
final String? result = await provider.getApplicationCachePath();
_verifySampleFile(result, 'applicationCache');
});
}
/// Verify a file called [name] in [directoryPath] by recreating it with test

View File

@ -1,4 +1,4 @@
// Copyright 2021 Sony Group Corporation. All rights reserved.
// Copyright 2023 Sony Group Corporation. All rights reserved.
// 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.
@ -13,14 +13,18 @@ void main() {
/// Sample app
class MyApp extends StatefulWidget {
/// Default Constructor
const MyApp({super.key});
@override
_MyAppState createState() => _MyAppState();
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String? _tempDirectory = 'Unknown';
String? _downloadsDirectory = 'Unknown';
String? _appSupportDirectory = 'Unknown';
String? _appCacheDirectory = 'Unknown';
String? _documentsDirectory = 'Unknown';
final PathProviderELinux _provider = PathProviderELinux();
@ -35,33 +39,36 @@ class _MyAppState extends State<MyApp> {
String? tempDirectory;
String? downloadsDirectory;
String? appSupportDirectory;
String? appCacheDirectory;
String? documentsDirectory;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
tempDirectory = await _provider.getTemporaryPath();
} on PlatformException catch (e, stackTrace) {
} on PlatformException {
tempDirectory = 'Failed to get temp directory.';
print('$tempDirectory $e $stackTrace');
}
try {
downloadsDirectory = await _provider.getDownloadsPath();
} on PlatformException catch (e, stackTrace) {
} on PlatformException {
downloadsDirectory = 'Failed to get downloads directory.';
print('$downloadsDirectory $e $stackTrace');
}
try {
documentsDirectory = await _provider.getApplicationDocumentsPath();
} on PlatformException catch (e, stackTrace) {
} on PlatformException {
documentsDirectory = 'Failed to get documents directory.';
print('$documentsDirectory $e $stackTrace');
}
try {
appSupportDirectory = await _provider.getApplicationSupportPath();
} on PlatformException catch (e, stackTrace) {
} on PlatformException {
appSupportDirectory = 'Failed to get documents directory.';
print('$appSupportDirectory $e $stackTrace');
}
try {
appCacheDirectory = await _provider.getApplicationCachePath();
} on PlatformException {
appCacheDirectory = 'Failed to get cache directory.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
@ -74,6 +81,7 @@ class _MyAppState extends State<MyApp> {
_tempDirectory = tempDirectory;
_downloadsDirectory = downloadsDirectory;
_appSupportDirectory = appSupportDirectory;
_appCacheDirectory = appCacheDirectory;
_documentsDirectory = documentsDirectory;
});
}
@ -83,7 +91,7 @@ class _MyAppState extends State<MyApp> {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Path Provider eLinux example app'),
title: const Text('Path Provider Linux example app'),
),
body: Center(
child: Column(
@ -92,6 +100,7 @@ class _MyAppState extends State<MyApp> {
Text('Documents Directory: $_documentsDirectory\n'),
Text('Downloads Directory: $_downloadsDirectory\n'),
Text('Application Support Directory: $_appSupportDirectory\n'),
Text('Application Cache Directory: $_appCacheDirectory\n'),
],
),
),

View File

@ -3,8 +3,8 @@ description: Demonstrates how to use the path_provider_elinux plugin.
publish_to: "none"
environment:
sdk: ">=2.12.0 <3.0.0"
flutter: ">=2.10.0"
sdk: ">=2.18.0 <4.0.0"
flutter: ">=3.3.0"
dependencies:
flutter:
@ -14,8 +14,6 @@ dependencies:
path: ../
dev_dependencies:
flutter_driver:
sdk: flutter
flutter_test:
sdk: flutter
integration_test:

View File

@ -1,48 +1,6 @@
// Copyright 2021 Sony Group Corporation. All rights reserved.
// Copyright 2023 Sony Group Corporation. All rights reserved.
// 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 'dart:io';
import 'package:path/path.dart' as path;
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
import 'package:xdg_directories/xdg_directories.dart' as xdg;
/// The elinux implementation of [PathProviderPlatform]
///
/// This class implements the `package:path_provider` functionality for eLinux
class PathProviderELinux extends PathProviderPlatform {
/// Registers this class as the default instance of [PathProviderPlatform]
static void registerWith() {
PathProviderPlatform.instance = PathProviderELinux();
}
@override
Future<String?> getTemporaryPath() {
return Future<String?>.value('/tmp');
}
@override
Future<String?> getApplicationSupportPath() async {
final String processName = path.basenameWithoutExtension(
await File('/proc/self/exe').resolveSymbolicLinks());
final Directory directory =
Directory(path.join(xdg.dataHome.path, processName));
// Creating the directory if it doesn't exist, because mobile implementations assume the directory exists
if (!directory.existsSync()) {
await directory.create(recursive: true);
}
return directory.path;
}
@override
Future<String?> getApplicationDocumentsPath() {
return Future<String?>.value(xdg.getUserDirectory('DOCUMENTS')?.path);
}
@override
Future<String?> getDownloadsPath() {
return Future<String?>.value(xdg.getUserDirectory('DOWNLOAD')?.path);
}
}
export 'src/path_provider_elinux.dart';

View File

@ -0,0 +1,9 @@
// 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.
// getApplicationId() is implemented using FFI; export a stub for platforms
// that don't support FFI (e.g., web) to avoid having transitive dependencies
// break web compilation.
export 'get_application_id_stub.dart'
if (dart.library.ffi) 'get_application_id_real.dart';

View File

@ -0,0 +1,78 @@
// 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 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:flutter/foundation.dart' show visibleForTesting;
// GApplication* g_application_get_default();
typedef _GApplicationGetDefaultC = IntPtr Function();
typedef _GApplicationGetDefaultDart = int Function();
// const gchar* g_application_get_application_id(GApplication* application);
typedef _GApplicationGetApplicationIdC = Pointer<Utf8> Function(IntPtr);
typedef _GApplicationGetApplicationIdDart = Pointer<Utf8> Function(int);
/// Interface for interacting with libgio.
@visibleForTesting
class GioUtils {
/// Creates a default instance that uses the real libgio.
GioUtils() {
try {
_gio = DynamicLibrary.open('libgio-2.0.so');
} on ArgumentError {
_gio = null;
}
}
DynamicLibrary? _gio;
/// True if libgio was opened successfully.
bool get libraryIsPresent => _gio != null;
/// Wraps `g_application_get_default`.
int gApplicationGetDefault() {
if (_gio == null) {
return 0;
}
final _GApplicationGetDefaultDart getDefault = _gio!
.lookupFunction<_GApplicationGetDefaultC, _GApplicationGetDefaultDart>(
'g_application_get_default');
return getDefault();
}
/// Wraps g_application_get_application_id.
Pointer<Utf8> gApplicationGetApplicationId(int app) {
if (_gio == null) {
return nullptr;
}
final _GApplicationGetApplicationIdDart gApplicationGetApplicationId = _gio!
.lookupFunction<_GApplicationGetApplicationIdC,
_GApplicationGetApplicationIdDart>(
'g_application_get_application_id');
return gApplicationGetApplicationId(app);
}
}
/// Allows overriding the default GioUtils instance with a fake for testing.
@visibleForTesting
GioUtils? gioUtilsOverride;
/// Gets the application ID for this app.
String? getApplicationId() {
final GioUtils gio = gioUtilsOverride ?? GioUtils();
if (!gio.libraryIsPresent) {
return null;
}
final int app = gio.gApplicationGetDefault();
if (app == 0) {
return null;
}
final Pointer<Utf8> appId = gio.gApplicationGetApplicationId(app);
if (appId == nullptr) {
return null;
}
return appId.toDartString();
}

View File

@ -0,0 +1,6 @@
// 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.
/// Gets the application ID for this app.
String? getApplicationId() => null;

View File

@ -0,0 +1,103 @@
// Copyright 2023 Sony Group Corporation. All rights reserved.
// 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 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
import 'package:xdg_directories/xdg_directories.dart' as xdg;
import 'get_application_id.dart';
/// The elinux implementation of [PathProviderPlatform]
///
/// This class implements the `package:path_provider` functionality for eLinux
class PathProviderELinux extends PathProviderPlatform {
/// Constructs an instance of [PathProviderELinux]
PathProviderELinux() : _environment = Platform.environment;
/// Constructs an instance of [PathProviderELinux] with the given [environment]
@visibleForTesting
PathProviderELinux.private(
{Map<String, String> environment = const <String, String>{},
String? executableName,
String? applicationId})
: _environment = environment,
_executableName = executableName,
_applicationId = applicationId;
final Map<String, String> _environment;
String? _executableName;
String? _applicationId;
/// Registers this class as the default instance of [PathProviderPlatform]
static void registerWith() {
PathProviderPlatform.instance = PathProviderELinux();
}
@override
Future<String?> getTemporaryPath() {
final String environmentTmpDir = _environment['TMPDIR'] ?? '';
return Future<String?>.value(
environmentTmpDir.isEmpty ? '/tmp' : environmentTmpDir,
);
}
@override
Future<String?> getApplicationSupportPath() async {
final Directory directory =
Directory(path.join(xdg.dataHome.path, await _getId()));
if (directory.existsSync()) {
return directory.path;
}
// This plugin originally used the executable name as a directory.
// Use that if it exists for backwards compatibility.
final Directory legacyDirectory =
Directory(path.join(xdg.dataHome.path, await _getExecutableName()));
if (legacyDirectory.existsSync()) {
return legacyDirectory.path;
}
// Create the directory, because mobile implementations assume the directory exists.
await directory.create(recursive: true);
return directory.path;
}
@override
Future<String?> getApplicationDocumentsPath() {
return Future<String?>.value(xdg.getUserDirectory('DOCUMENTS')?.path);
}
@override
Future<String?> getApplicationCachePath() async {
final Directory directory =
Directory(path.join(xdg.cacheHome.path, await _getId()));
if (!directory.existsSync()) {
await directory.create(recursive: true);
}
return directory.path;
}
@override
Future<String?> getDownloadsPath() {
return Future<String?>.value(xdg.getUserDirectory('DOWNLOAD')?.path);
}
// Gets the name of this executable.
Future<String> _getExecutableName() async {
_executableName ??= path.basenameWithoutExtension(
await File('/proc/self/exe').resolveSymbolicLinks());
return _executableName!;
}
// Gets the unique ID for this application.
Future<String> _getId() async {
_applicationId ??= getApplicationId();
// If no application ID then fall back to using the executable name.
return _applicationId ?? await _getExecutableName();
}
}

View File

@ -2,11 +2,11 @@ name: path_provider_elinux
description: eLinux implementation of the path_provider plugin
homepage: https://github.com/sony/flutter-elinux-plugins
repository: https://github.com/sony/flutter-elinux-plugins/tree/main/packages/path_provider
version: 1.0.2
version: 2.2.0
environment:
sdk: ">=2.12.0 <3.0.0"
flutter: ">=2.10.0"
sdk: ">=2.18.0 <4.0.0"
flutter: ">=3.3.0"
flutter:
plugin:
@ -17,11 +17,12 @@ flutter:
pluginClass: none
dependencies:
ffi: ">=1.1.2 <3.0.0"
flutter:
sdk: flutter
path: ^1.8.0
path_provider_platform_interface: ^2.0.0
xdg_directories: ^0.2.0
path_provider_platform_interface: ^2.1.0
xdg_directories: ">=0.2.0 <2.0.0"
dev_dependencies:
flutter_test:

View File

@ -1,9 +1,11 @@
// Copyright 2023 Sony Group Corporation. All rights reserved.
// 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_test/flutter_test.dart';
import 'package:path_provider_elinux/path_provider_elinux.dart';
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
import 'package:xdg_directories/xdg_directories.dart' as xdg;
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
@ -13,14 +15,42 @@ void main() {
expect(PathProviderPlatform.instance, isA<PathProviderELinux>());
});
test('getTemporaryPath', () async {
final PathProviderPlatform plugin = PathProviderPlatform.instance;
test('getTemporaryPath defaults to TMPDIR', () async {
final PathProviderPlatform plugin = PathProviderELinux.private(
environment: <String, String>{'TMPDIR': '/run/user/0/tmp'},
);
expect(await plugin.getTemporaryPath(), '/run/user/0/tmp');
});
test('getTemporaryPath uses fallback if TMPDIR is empty', () async {
final PathProviderPlatform plugin = PathProviderELinux.private(
environment: <String, String>{'TMPDIR': ''},
);
expect(await plugin.getTemporaryPath(), '/tmp');
});
test('getTemporaryPath uses fallback if TMPDIR is unset', () async {
final PathProviderPlatform plugin = PathProviderELinux.private(
environment: <String, String>{},
);
expect(await plugin.getTemporaryPath(), '/tmp');
});
test('getApplicationSupportPath', () async {
final PathProviderPlatform plugin = PathProviderPlatform.instance;
expect(await plugin.getApplicationSupportPath(), startsWith('/'));
final PathProviderPlatform plugin = PathProviderELinux.private(
executableName: 'path_provider_elinux_test_binary',
applicationId: 'com.example.Test');
// Note this will fail if ${xdg.dataHome.path}/path_provider_linux_test_binary exists on the local filesystem.
expect(await plugin.getApplicationSupportPath(),
'${xdg.dataHome.path}/com.example.Test');
});
test('getApplicationSupportPath uses executable name if no application Id',
() async {
final PathProviderPlatform plugin = PathProviderELinux.private(
executableName: 'path_provider_elinux_test_binary');
expect(await plugin.getApplicationSupportPath(),
'${xdg.dataHome.path}/path_provider_elinux_test_binary');
});
test('getApplicationDocumentsPath', () async {
@ -28,6 +58,13 @@ void main() {
expect(await plugin.getApplicationDocumentsPath(), startsWith('/'));
});
test('getApplicationCachePath', () async {
final PathProviderPlatform plugin = PathProviderELinux.private(
executableName: 'path_provider_elinux_test_binary');
expect(await plugin.getApplicationCachePath(),
'${xdg.cacheHome.path}/path_provider_elinux_test_binary');
});
test('getDownloadsPath', () async {
final PathProviderPlatform plugin = PathProviderPlatform.instance;
expect(await plugin.getDownloadsPath(), startsWith('/'));