Skip to content

[path_provider] added android support for getDownloadsDirectory #4167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed

[path_provider] added android support for getDownloadsDirectory #4167

wants to merge 7 commits into from

Conversation

zopagaduanjr
Copy link
Contributor

@zopagaduanjr zopagaduanjr commented Jun 8, 2023

Followed step 3. of this approach flutter/plugins#4559 (review)

Fixes flutter/flutter#93198

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the relevant style guides and ran the auto-formatter. (Unlike the flutter/flutter repo, the flutter/packages repo does use dart format.)
  • I signed the CLA.
  • The title of the PR starts with the name of the package surrounded by square brackets, e.g. [shared_preferences]
  • I listed at least one issue that this PR fixes in the description above.
  • I updated pubspec.yaml with an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.
  • I updated CHANGELOG.md to add a description of the change, following repository CHANGELOG style.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Copy link
Contributor

@camsim99 camsim99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix! This looks good to me, just a couple of requested changes.

if (paths != null && paths.isNotEmpty) {
return paths.first;
} else {
throw UnsupportedError('getDownloadsPath is not supported on Android');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe change the error to something that references the empty path since it is now supported on Android?

@camsim99 camsim99 requested a review from stuartmorgan-g June 12, 2023 16:39
if (paths != null && paths.isNotEmpty) {
return paths.first;
} else {
throw UnsupportedError('getDownloadsPath is not supported on Android');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UnsupportedError is incorrect here; the function is supported. This would kill someone's app (because it's an Error, which isn't meant to be caught) if the underlying API call failed, which is not a programming error by the caller.

Why isn't this just returning null?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in hindsight, i was thinking to notify the user that downloads path is not found. but the function returns a nullable string and the main function getDownloadsDirectory also returns a nullable directory, hence returning null should be correct.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in hindsight, i was thinking to notify the user that downloads path is not found.

In Dart, an Error is never the correct mechanism for that. Per the docs: "An Error object represents a program failure that the programmer should have avoided." A programmer cannot avoid Android not finding the download folder, so that's not a case that should ever be represented by an Error.

}
test('getDownloadsPath succeeds', () async {
final String? path = await pathProvider.getDownloadsPath();
expect(path, kExternalStoragePaths);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two code paths through the new method, success and failure. Each path needs a unit test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i've updated the new method to return a nullable path

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You still need a test for the case where it fails (e.g., to catch the fact that your current code will, incorrectly, throw if no external storage paths are returned).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current function now only returns a path, one code path, so I think 1 test is enough? (getDownloadsPath succeed)

Cause it no longer throws an error, hence in test we can't expect it to throw something.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current function now only returns a path, one code path, so I think 1 test is enough? (getDownloadsPath succeed)

As my comment above says, there is a bug in your current implementation, which is compelling evidence that the current test is insufficient.

Cause it no longer throws an error

Please test your code with an empty return array if you don't believe me that your code can still throw.

Copy link
Contributor Author

@zopagaduanjr zopagaduanjr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • updated to return a nullable path.
  • removed the unnecessary throw UnsupportedError.

Copy link
Contributor Author

@zopagaduanjr zopagaduanjr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated changelog

@@ -81,7 +81,9 @@ class PathProviderAndroid extends PathProviderPlatform {
}

@override
Future<String?> getDownloadsPath() {
throw UnsupportedError('getDownloadsPath is not supported on Android');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed incorrect throw error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[path_provider] getDownloadsDirectory() doesn't work for iOS and Android.
4 participants