Skip to content

Commit

Permalink
[path_provider] Add Windows support (flutter#2818)
Browse files Browse the repository at this point in the history
Implements path_provider for Windows, adding path_provider_windows and endorsing it in path_provider.
  • Loading branch information
Tim Sneath authored and jorgefspereira committed Oct 10, 2020
1 parent 7319017 commit aba492d
Show file tree
Hide file tree
Showing 20 changed files with 946 additions and 41 deletions.
5 changes: 5 additions & 0 deletions packages/path_provider/path_provider/CHANGELOG.md
@@ -1,3 +1,8 @@
## 1.6.15

* Endorse Windows implementation.
* Remove the need to call disablePathProviderPlatformOverride in tests

## 1.6.14

* Update package:e2e -> package:integration_test
Expand Down
9 changes: 1 addition & 8 deletions packages/path_provider/path_provider/README.md
Expand Up @@ -23,14 +23,7 @@ Please see the example app of this plugin for a full example.

### Usage in tests

`path_provider` now uses a `PlatformInterface`, meaning that not all platforms share the a single `PlatformChannel`-based implementation.
`path_provider` now uses a `PlatformInterface`, meaning that not all platforms share the a single `PlatformChannel`-based implementation.
With that change, tests should be updated to mock `PathProviderPlatform` rather than `PlatformChannel`.

See this `path_provider` [test](https://github.com/flutter/plugins/blob/master/packages/path_provider/path_provider/test/path_provider_test.dart) for an example.

You will also have to temporarily add the following line to the setup of your test.
```dart
disablePathProviderPlatformOverride = true;
```

See this [issue](https://github.com/flutter/flutter/issues/52267), for more details on why this is needed.
47 changes: 21 additions & 26 deletions packages/path_provider/path_provider/lib/path_provider.dart
Expand Up @@ -7,42 +7,37 @@ import 'dart:io' show Directory, Platform;

import 'package:flutter/foundation.dart' show kIsWeb, visibleForTesting;
import 'package:path_provider_linux/path_provider_linux.dart';
import 'package:path_provider_windows/path_provider_windows.dart';
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
import 'package:path_provider_platform_interface/src/method_channel_path_provider.dart';

export 'package:path_provider_platform_interface/path_provider_platform_interface.dart'
show StorageDirectory;

/// Disables platform override in order to use a manually registered [PathProviderPlatform], only for testing right now
///
/// Make sure to disable the override before using any of the `path_provider` methods
/// To use your own [PathProviderPlatform], make sure to include the following lines
/// ```
/// PathProviderPlatform.instance = YourPathProviderPlatform();
/// disablePathProviderPlatformOverride = true;
/// // Use the `path_provider` methods:
/// final dir = await getTemporaryDirectory();
/// ```
/// See this issue https://github.com/flutter/flutter/issues/52267 for why this is required
@visibleForTesting
set disablePathProviderPlatformOverride(bool override) {
_disablePlatformOverride = override;
}
@Deprecated('This is no longer necessary, and is now a no-op')
set disablePathProviderPlatformOverride(bool override) {}

bool _disablePlatformOverride = false;
PathProviderPlatform __platform;
bool _manualDartRegistrationNeeded = true;

// This is to manually endorse the linux path provider until automatic registration of dart plugins is implemented.
// See this issue https://github.com/flutter/flutter/issues/52267 for details
PathProviderPlatform get _platform {
if (__platform != null) {
return __platform;
}
if (!kIsWeb && Platform.isLinux && !_disablePlatformOverride) {
__platform = PathProviderLinux();
} else {
__platform = PathProviderPlatform.instance;
// This is to manually endorse Dart implementations until automatic
// registration of Dart plugins is implemented. For details see
// https://github.com/flutter/flutter/issues/52267.
if (_manualDartRegistrationNeeded) {
// Only do the initial registration if it hasn't already been overridden
// with a non-default instance.
if (!kIsWeb && PathProviderPlatform.instance is MethodChannelPathProvider) {
if (Platform.isLinux) {
PathProviderPlatform.instance = PathProviderLinux();
} else if (Platform.isWindows) {
PathProviderPlatform.instance = PathProviderWindows();
}
}
_manualDartRegistrationNeeded = false;
}
return __platform;

return PathProviderPlatform.instance;
}

/// Path to the temporary directory on the device that is not backed up and is
Expand Down
8 changes: 5 additions & 3 deletions packages/path_provider/path_provider/pubspec.yaml
@@ -1,8 +1,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.
description: Flutter plugin for getting commonly used locations on host platform 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.14
version: 1.6.15

flutter:
plugin:
Expand All @@ -16,13 +15,16 @@ flutter:
default_package: path_provider_macos
linux:
default_package: path_provider_linux
windows:
default_package: path_provider_windows

dependencies:
flutter:
sdk: flutter
path_provider_platform_interface: ^1.0.1
path_provider_macos: ^0.0.4
path_provider_linux: ^0.0.1
path_provider_windows: ^0.0.1

dev_dependencies:
integration_test:
Expand Down
Expand Up @@ -25,10 +25,6 @@ void main() {

setUp(() async {
PathProviderPlatform.instance = MockPathProviderPlatform();
// This is required because we manually register the Linux path provider when on the Linux platform.
// Will be removed when automatic registration of dart plugins is implemented.
// See this issue https://github.com/flutter/flutter/issues/52267 for details
disablePathProviderPlatformOverride = true;
});

test('getTemporaryDirectory', () async {
Expand Down
3 changes: 3 additions & 0 deletions packages/path_provider/path_provider_windows/.gitignore
@@ -0,0 +1,3 @@
.packages
.flutter-plugins
pubspec.lock
11 changes: 11 additions & 0 deletions packages/path_provider/path_provider_windows/CHANGELOG.md
@@ -0,0 +1,11 @@
## 0.0.2

* README update for endorsement.
* Changed getApplicationSupportPath location.
* Removed getLibraryPath.

## 0.0.1+2

* The initial implementation of path_provider for Windows
* Implements getTemporaryPath, getApplicationSupportPath, getLibraryPath,
getApplicationDocumentsPath and getDownloadsPath.
25 changes: 25 additions & 0 deletions packages/path_provider/path_provider_windows/LICENSE
@@ -0,0 +1,25 @@
Copyright 2017 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.
31 changes: 31 additions & 0 deletions packages/path_provider/path_provider_windows/README.md
@@ -0,0 +1,31 @@
# path_provider_windows

The Windows implementation of [`path_provider`][1].

**Please set your constraint to `path_provider_windows: '>=0.0.y+x <2.0.0'`**

## Backward compatible 1.0.0 version is coming

The plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.0.y+z`.
Please use `path_provider_windows: '>=0.0.y+x <2.0.0'` as your dependency constraint to allow a smoother ecosystem migration.
For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0

## Usage

### Import the package

This package has been endorsed, meaning that you only need to add `path_provider`
as a dependency in your `pubspec.yaml`. It will be automatically included in your app
when you depend on `package:path_provider`.

This is what the above means to your `pubspec.yaml`:

```yaml
...
dependencies:
...
path_provider: ^1.6.15
...
```

[1]:../
44 changes: 44 additions & 0 deletions packages/path_provider/path_provider_windows/example/.gitignore
@@ -0,0 +1,44 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/

# Web related
lib/generated_plugin_registrant.dart

# Symbolication related
app.*.symbols

# Obfuscation related
app.*.map.json

# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
10 changes: 10 additions & 0 deletions packages/path_provider/path_provider_windows/example/.metadata
@@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: f2320c3b7a42bc27e7f038212eed1b01f4269641
channel: master

project_type: app
@@ -0,0 +1,8 @@
# path_provider_windows_example

Demonstrates how to use the path_provider_windows plugin.

## Getting Started

For help getting started with Flutter, view our online
[documentation](http://flutter.io/).
93 changes: 93 additions & 0 deletions packages/path_provider/path_provider_windows/example/lib/main.dart
@@ -0,0 +1,93 @@
// 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.

// ignore_for_file: public_member_api_docs

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:path_provider_windows/path_provider_windows.dart';

void main() async {
runApp(MyApp());
}

/// Sample app
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
String _tempDirectory = 'Unknown';
String _downloadsDirectory = 'Unknown';
String _appSupportDirectory = 'Unknown';
String _documentsDirectory = 'Unknown';

@override
void initState() {
super.initState();
initDirectories();
}

// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initDirectories() async {
String tempDirectory;
String downloadsDirectory;
String appSupportDirectory;
String documentsDirectory;
final PathProviderWindows provider = PathProviderWindows();

try {
tempDirectory = await provider.getTemporaryPath();
} catch (exception) {
tempDirectory = 'Failed to get temp directory: $exception';
}
try {
downloadsDirectory = await provider.getDownloadsPath();
} catch (exception) {
downloadsDirectory = 'Failed to get downloads directory: $exception';
}

try {
documentsDirectory = await provider.getApplicationDocumentsPath();
} catch (exception) {
documentsDirectory = 'Failed to get documents directory: $exception';
}

try {
appSupportDirectory = await provider.getApplicationSupportPath();
} catch (exception) {
appSupportDirectory = 'Failed to get app support directory: $exception';
}

setState(() {
_tempDirectory = tempDirectory;
_downloadsDirectory = downloadsDirectory;
_appSupportDirectory = appSupportDirectory;
_documentsDirectory = documentsDirectory;
});
}

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Path Provider example app'),
),
body: Center(
child: Column(
children: [
Text('Temp Directory: $_tempDirectory\n'),
Text('Documents Directory: $_documentsDirectory\n'),
Text('Downloads Directory: $_downloadsDirectory\n'),
Text('Application Support Directory: $_appSupportDirectory\n'),
],
),
),
),
);
}
}
21 changes: 21 additions & 0 deletions packages/path_provider/path_provider_windows/example/pubspec.yaml
@@ -0,0 +1,21 @@
name: path_provider_example
description: Demonstrates how to use the path_provider plugin.

dependencies:
flutter:
sdk: flutter
path_provider_windows: any

dependency_overrides:
path_provider_windows:
path: ../

dev_dependencies:
e2e: ^0.2.1
flutter_driver:
sdk: flutter
test: any
pedantic: ^1.8.0

flutter:
uses-material-design: true

0 comments on commit aba492d

Please sign in to comment.