Skip to content
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

Do not ask for storage permissions when it's a fresh installation #4297

Merged
merged 48 commits into from
Jan 26, 2021

Conversation

grzesiek2010
Copy link
Member

@grzesiek2010 grzesiek2010 commented Dec 11, 2020

Closes #4288

What has been done to verify that this works as intended?

I tested the behavior.

Why is this the best possible solution? Were any other approaches considered?

I decided to call requestStoragePermissions() like before but add one trick which is here:
https://github.com/getodk/collect/pull/4297/files#diff-fe2bc5034d6dfe946ff681f198d0552c83038caed992865f5e7ce030447a276bR98

Another option would be to check if we need storage permission before calling requestStoragePermissions() but that would require adding more if/else statements and the code would be more cluttered.

How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?

Fresh installs should not ask for storage permission that's the only change. In order to confirm that everything works fine it would be good to go through some functionalities where normally we would be asked for permissions.

Do we need any specific form for testing your changes? If so, please attach one.

No.

Does this change require updates to documentation? If so, please file an issue here and include the link below.

No.

Before submitting this PR, please make sure you have:

  • run ./gradlew checkAll and confirmed all checks still pass OR confirm CircleCI build passes and run ./gradlew connectedDebugAndroidTest locally.
  • verified that any code or assets from external sources are properly credited in comments and/or in the about file.
  • verified that any new UI elements use theme colors. UI Components Style guidelines

@grzesiek2010 grzesiek2010 force-pushed the COLLECT-4288 branch 2 times, most recently from 4289b3a to fc3b134 Compare January 7, 2021 13:52
@grzesiek2010 grzesiek2010 marked this pull request as ready for review January 7, 2021 14:10
Copy link
Member

@lognaturel lognaturel left a comment

Choose a reason for hiding this comment

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

Would be great to get some testing. Maybe just a small test for areStoragePermissionsGranted that verifies that true is always returned if scoped storage is enabled?

I like what you've done with PermissionUtils. I'm wondering whether it's also a good opportunity to rename it to maybe PermissionsRequester or PermissionsProvider?

@grzesiek2010
Copy link
Member Author

Would be great to get some testing

I thought the same at the end of my day yesterday. I'll try to add something valuable.

@grzesiek2010
Copy link
Member Author

Would be great to get some testing. Maybe just a small test for areStoragePermissionsGranted that verifies that true is always returned if scoped storage is enabled?

I like what you've done with PermissionUtils. I'm wondering whether it's also a good opportunity to rename it to maybe PermissionsRequester or PermissionsProvider?

It's ready, I added some tests and implemented code refactoring.

Copy link
Member

@lognaturel lognaturel left a comment

Choose a reason for hiding this comment

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

Looks good other than the main test... 🙃 Feel free to mark as needs testing once that's fixed and conflicts are resolved.

public static String getFileExtensionFromUri(Uri fileUri) {
String mimeType = getContentResolver().getType(fileUri);

String extension = fileUri.getScheme() != null && fileUri.getScheme().equals(ContentResolver.SCHEME_CONTENT)
Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't we always be dealing with content URIs here? In what cases would we have file URIs?

Copy link
Member

Choose a reason for hiding this comment

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

Or was that the selfie video case again?

Copy link
Member Author

Choose a reason for hiding this comment

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

This was the fix added for a crash some time ago f98b98d so I wanted to keep it just in case seeing how other cases might be tricky.

Copy link
Member

Choose a reason for hiding this comment

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

Got it. Would be great to follow up with #2834 because this method has gone through lots of big changes during this PR that probably would have been avoided with tests.

@grzesiek2010
Copy link
Member Author

@lognaturel Generally I think it's ready for testing unless you see something important.

Copy link
Member

@lognaturel lognaturel left a comment

Choose a reason for hiding this comment

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

This has turned into an adventure! Good to see so much code going away.

Lots of little things to check around the media selection questions like are temporary files cleaned up and all the cases around MIME types and file extensions I listed earlier.

@grzesiek2010
Copy link
Member Author

I added some improvements to handle SecurityException which is thrown when read permission is no granted to the returned uri. I was even able to reproduce it on an emulator Api 25 where I can't record video because apparently the default app doesn't grant read permission to returned uri. Please keep an eye on it during testing.

@lognaturel
Copy link
Member

I was even able to reproduce it on an emulator Api 25

Nice. But does this mean that recording video with that default app would never work? I wonder if this is going to be a broader issue -- are media apps for older OS versions not going to work because they expect the blanket read permissions to be given?

@grzesiek2010
Copy link
Member Author

grzesiek2010 commented Jan 26, 2021

Nice. But does this mean that recording video with that default app would never work? I wonder if this is going to be a broader issue -- are media apps for older OS versions not going to work because they expect the blanket read permissions to be given?

I tested emulators with apis 22-30 and noticed that problem on api 23 and 25. In those cases recording is not possible with default camera apps. Granting storage permission fixes the issue but I thought it was a bug in those camera apps. In the doc where recording videos is described https://developer.android.com/training/camera/videobasics there is nothing about storage permission and we use exactly that way.

Apparently they love to confuse people.

I also read https://developer.android.com/training/data-storage/shared/media and https://developer.android.com/training/data-storage/shared/documents-files and my understanding is that we shouldn't need that permissions.

@mmarciniak90
Copy link
Contributor

Tested with success

Verified on Android 7.0, 8.1, 10.0

Verified cases:

  • Image widgets
    • choose image from Image directory
    • choose image from Downloads
    • choose image from Google Drive
    • take new photo
    • Camera permissions
  • Audio widget
    • choose audio file from Audio directory
    • choose audio file from Downloads
    • choose audio file from Google Drive
    • record new audio
    • Microphone permissions
  • Video widget
    • choose video file from Video directory
    • choose video file from Downloads
    • choose video file from Google Drive
    • record new video
    • Camera and Microphone permissions
  • File widget
    • choose any file for file widget from Images/Videos/Audio
    • choose any file for file widget from Downloads
    • choose any file for file widget from Google Drive
    • verified file types: amr, ogg, m4a, mp3, 3gp, gif, jpeg, jpg, png, pdf, doc, docx, txt, xls, xlsx, csv, xml, rtf, zip, rar files
  • Location permissions
  • Contact permissions
  • Telephone permissions
  • enabled storage permission manually
  • fresh installation
  • import settings using a qr code file
  • import settings from .settings / json file
  • custom splash screen images - file saved in /storage/emulated/0/Android/data/org.odk.collect.android/files
  • upgrade when storage permission is enabled
  • upgrade when storage permission is disabled
    • if files are migrated, storage permissions are not required
    • if files are not migrated, storage permissions are required
  • jpg with the correct MIME type but no extension (internal storage and GD) - verified on images widgets and file widget
  • text file with extension .fake and the correct MIME type (internal storage and GD) - verified on file widget

@kkrawczyk123
Copy link
Contributor

Verified also on Androids 5.1, 7.1 and 9.0.

@getodk-bot unlabel "needs testing"
@getodk-bot label "behavior verified"

@grzesiek2010
Copy link
Member Author

Regarding that problems with permissions: If it's not our fault bug external apps that do not grant uri permission we may need to consider adding something like: 17431bb

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.

Do not ask for storage permissions users who use scoped storage
6 participants