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

Android 13 update #2683

Merged
merged 21 commits into from
Sep 20, 2023
Merged

Android 13 update #2683

merged 21 commits into from
Sep 20, 2023

Conversation

avazirna
Copy link
Contributor

@avazirna avazirna commented Jul 25, 2023

Summary

This PR implements the changes required to support Android 13. The most relevant are:

  • Nearby Wi-Fi devices permission - from Android 13, access to devices via Wi-Fi are no longer through the ACCESS_FINE_LOCATION permission. Apps that call any of these Wi-Fi APIs need to request the NEARBY_WIFI_PERMISSION;
  • POST_NOTIFICATION permission - Google is invested in making sure users' wishes around notifications are respected, this means that users can now very easily revoke permissions around notifications. This motivated changes in places where notifications are triggered to skip them when the permission is not granted;
  • Stop Foreground services - this feature causes the system to remove the app from memory, which makes the app to stop, not just the Foreground service. CommCare seems to handle this elegantly, so no changes were done. The video below shows the behavior:
Screen.Recording.2023-09-13.at.01.11.48.mov

Safety Assurance

  • I have confidence that this PR will not introduce a regression for the reasons below

Safety story

I had the opportunity to run some smoke tests around the affected parts of the code and it ran well, however, some Instrumentation tests became flakier than usual, I think it's something to look into.
A few questions for reviewers:

  • Are there any concerns with the user stopping the Foreground Service, and subsequently CommCare, that we should account for?
  • Regarding the approach when the POST_NOTIFICATION permission is revoked, it seems to me that the approach should be around preventing notifications from being triggered but I wonder if there are other options we should explore.
  • Android 13 introduces Predictive back gesture and recommends its adoption as soon as possible, it seems fine to me to migrate later but happy to be persuaded otherwise. Any comments?

cross-request: dimagi/commcare-core#1329

QA Note: Testing for Android 13

@avazirna
Copy link
Contributor Author

@damagatchi retest this please

@avazirna
Copy link
Contributor Author

@damagatchi retest this please

@avazirna
Copy link
Contributor Author

@damagatchi retest this please

1 similar comment
@avazirna
Copy link
Contributor Author

@damagatchi retest this please

@avazirna avazirna force-pushed the android_13_update branch 3 times, most recently from aeb6e4b to beff040 Compare September 14, 2023 00:05
@avazirna
Copy link
Contributor Author

@damagatchi retest this please

@avazirna avazirna marked this pull request as ready for review September 14, 2023 00:23
@avazirna
Copy link
Contributor Author

@shubham1g5 I was planning to PR the Support Library changes separately, but the decided to include here considering that there aren't many

@avazirna avazirna added this to the 2.54 milestone Sep 14, 2023
@avazirna avazirna self-assigned this Sep 14, 2023
@avazirna
Copy link
Contributor Author

@damagatchi retest this please

Copy link
Contributor

@shubham1g5 shubham1g5 left a comment

Choose a reason for hiding this comment

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

I took a quick look and Looks good overall. I plan to take another deeper look into changes but leaving some high level notes until then.

Manifest.permission.READ_MEDIA_AUDIO,
Manifest.permission.READ_MEDIA_VIDEO}));
}
else{
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: formatting

Manifest.permission.CALL_PHONE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Copy link
Contributor

Choose a reason for hiding this comment

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

do we not need to request WRITE permissions exolicitly anymore for api 33 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@shubham1g5 it has been deprecated, so it has no effect on devices running Android 13.

Copy link
Contributor

Choose a reason for hiding this comment

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

So does the READ_MEDIA_IMAGES gives permissions for both reading and writing images to the storage ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@shubham1g5 not necessarily, my understanding is that from Android 10 with the introduction of scoped storage, apps don't actually need permission to write in their specific folders and we also don't need permissions to write to shared storage (considering that the app owns the files it creates). I just wonder if there are any use cases we should be concerned about? I looked into this and ran a few tests and it seems that we don't

@@ -104,7 +104,8 @@ public static String[] getAppPermissions() {
appPermissions.addAll(Arrays.asList(new String[]{
Manifest.permission.READ_MEDIA_IMAGES,
Manifest.permission.READ_MEDIA_AUDIO,
Manifest.permission.READ_MEDIA_VIDEO}));
Manifest.permission.READ_MEDIA_VIDEO,
Manifest.permission.NEARBY_WIFI_DEVICES}));
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we only request this permission later on in the wifi direct screen ? Most users will never access wifi direct feature and it doesn't seem right to ask for the permission upfront for such a rare use case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree

Comment on lines 120 to 127
showingPermissionDialog.observe(this, value -> {
if (value == REJECT_FEATURE){
informUserAboutFeatureUnavailability();
}
else if (value == REQUEST_PERMISSION){
showNearbyWiFiPermissionRationale();
}
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we move all wifi-direct permission handling in CommCareWiFiDirectActivity itself ? It doesn't make much sense to me for this code to be in preference class as it doesn't access any APIs behind this permission directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@shubham1g5 I battled with this a bit, the reasoning was to prevent the creation of CommCareWiFiDirectActivity ini case the permission was not granted, which happens in the AdvancedActionsPreference. It does feel misplaced having it there, but within CommCareWiFiDirectActivity we will need to put behind the Transfer and Receive options.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can't we simply add the permission check in onCreate for CommCareWiFiDirectActivity and show user an error if the permission is not granted on the same screen ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@shubham1g5 we can, but where should we trigger the permission request workflow, in case the user hasn't yet been asked?

Copy link
Contributor

Choose a reason for hiding this comment

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

you can trigger it in onCreate for CommCareWiFiDirectActivity itself if the permission is not given already.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines 150 to 157
public boolean areNotificationsEnabled() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return ((NotificationManager)context.getSystemService(NOTIFICATION_SERVICE))
.areNotificationsEnabled();
}
else {
return true;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: all the new code should be formatted as per our style files.

} else {
updateMessageNotification();

if (areNotificationsEnabled()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do mNM.cancel require permission as well ? If not, What do you think of putting this check at just one place at start of updateMessageNotification ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@@ -83,7 +83,9 @@ object MissingMediaDownloadHelper : TableStateListener {

RequestStats.register(InstallRequestSource.BACKGROUND_LAZY_RESOURCE)
global.setInstallCancellationChecker(cancellationChecker)
startPinnedNotification()
if (CommCareApplication.notificationManager().areNotificationsEnabled()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: should put this check in the startPinnedNotification() method itself

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines 120 to 127
showingPermissionDialog.observe(this, value -> {
if (value == REJECT_FEATURE){
informUserAboutFeatureUnavailability();
}
else if (value == REQUEST_PERMISSION){
showNearbyWiFiPermissionRationale();
}
});
Copy link
Contributor

Choose a reason for hiding this comment

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

you can trigger it in onCreate for CommCareWiFiDirectActivity itself if the permission is not given already.

@@ -268,7 +272,9 @@ private static LogSubmitOutcomes submitDeviceReportRecord(DeviceReportRecord slr
return LogSubmitOutcomes.SUBMITTED;
}

listener.startSubmission(index, f.length());
if (listener != null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: add @Nullable to the global variable declation for listener to signify it can be null

Comment on lines 96 to 103
if (CommCareApplication.notificationManager().areNotificationsEnabled()) {
reportSubmitter = new LogSubmissionTask(
CommCareApplication.instance().getSession().getListenerForSubmissionNotification(R.string.submission_logs_title),
url,
forceLogs);
} else {
reportSubmitter = new LogSubmissionTask(url, forceLogs);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: formatting seems off

REQUEST_PERMISSION;
}

{
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice pattern!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks

@shubham1g5 shubham1g5 merged commit faa5a5b into master Sep 20, 2023
4 of 10 checks passed
@shubham1g5 shubham1g5 deleted the android_13_update branch September 20, 2023 16:51
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.

None yet

2 participants