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

Target Android 14 (set targetSdkVersion to 34), by 2023-10 deadline #5877

Open
gnprice opened this issue Jul 10, 2024 · 7 comments
Open

Target Android 14 (set targetSdkVersion to 34), by 2023-10 deadline #5877

gnprice opened this issue Jul 10, 2024 · 7 comments

Comments

@gnprice
Copy link
Member

gnprice commented Jul 10, 2024

This is the successor to #5453 (and an annual series of previous issues linked from there). We should update our targetSdkVersion to 34, meaning Android 14.

The deadline is earlier this year than in some previous years: it's 2024-08-31. (Much like last year, we can request an extension to 2024-11-01.) is 2024-10-31, after I requested an extension.

The important steps for this upgrade are:

  1. Read about the potentially-breaking changes, and identify those that might affect us.
    (edit: Also the changes not tied to targetSdkVersion, because for Android 13 last year a change that should have been in the first doc wasn't, and bit us, and the latter doc had an item that would have raised our suspicions if we'd read that doc closely.)
  2. Make a WIP change to targetSdkVersion.
  3. Test the WIP change thoroughly, especially in the areas highlighted in step 1. Fix things as needed, and repeat.
@chrisbobbe
Copy link
Contributor

chrisbobbe commented Jul 10, 2024

From that potentially-breaking changes article:

  • Core functionality:
    • Foreground service types are required
      • We don't have any foreground services AFAICT.
    • Enforcement of BLUETOOTH_CONNECT permission in BluetoothAdapter
      • We don't use Bluetooth. @react-native-community/netinfo doesn't use the BluetoothAdapter API mentioned in the article.
    • OpenJDK 17 updates
      • Regexes are used by react-native-webview in a custom DownloadListener…I think we don't allow downloads directly from the WebView, so this should be moot?
      • A few regexes are used in react-native, in […]/animated/InterpolationAnimatedNode.java, […]/devsupport/BundleDownloader.java, […]/devsupport/StackTraceHelper.java, […]/util/JSStackTrace.java. Probably any issues will get discovered in manual testing?
      • expo-constants uses UUID.fromString but it looks like it might already handle IllegalArgumentException in that code?
      • We don't use ProGuard so I don't think the point about ProGuard is relevant.
    • JobScheduler reinforces callback and network behavior
      • I don't think we use JobScheduler; irrelevant.
    • Tiles launch API
      • I don't think we use TileService; irrelevant.
  • Privacy:
    • Partial access to photos and videos
      • I'm getting confused about this one. It seems like as long as we use "the photo picker", then we don't need any image/video access permissions, because image selection is done through an external system that only gives our app access to specific media the user chooses. When we bumped targetSdkVersion to 33 in 6f44474, we wrote down that we do use "Android's PhotoPicker API", because we upgraded react-native-image-picker. That upgrade included a commit that said "add new PhotoPicker API for Android 13 Teramisu"…but no code with "PhotoPicker" was added; instead it started using something called MediaStore, which is still used in react-native-image-picker at main. And there's an open issue for "Using Android's Photo Picker instead of Media Store", which links to an Android doc to show how they're different.
      • So I think it's possible that this part in the behavior-changes doc will apply to us: "If your app doesn't use the new permission, the system runs your app in a compatibility mode."
      • In any case we should probably test our upload flows manually, on an Android 14 device and a non-Android 14 device (done; image upload from camera and library worked on the office Android device, and we don't support video uploads from either source on Android 9).
  • User experience:
    • Secure full-screen Intent notifications
      • We don't use full-screen intents; irrelevant. (It's a feature for showing extremely high-priority notifications like phone calls and alarms.)
  • Security:
    • I'd appreciate Greg's review of these.
    • Restrictions to implicit and pending intents
    • Runtime-registered broadcasts receivers must specify export behavior
    • Safer dynamic code loading
    • Additional restrictions on starting activities from the background
    • Zip path traversal
    • User consent required for each MediaProjection capture session
      • We don't use MediaProjection; it says "A token granting applications the ability to capture screen contents and/or record system audio." Irrelevant.
  • Updated non-SDK restrictions
    • A linked doc says any issues of this kind would show up in the Play Console, and I checked and didn't see any.

@chrisbobbe
Copy link
Contributor

Quick manual testing on the office Android device (Android 9) showed no problems, which I guess isn't surprising because it's not Android 14. The app opened without crashing; notifications worked, with the app foregrounded/backgrounded/closed; and image uploads worked, both from the camera and the media library. (We don't support video uploads from the media library prior to Android 13, and we don't support video uploads from the camera on Android at all.)

chrisbobbe added a commit to chrisbobbe/zulip-mobile that referenced this issue Jul 10, 2024
As we said on the last one of these, fc2dab7:

  This setting is not to be confused with the targetSdkVersion. The
  latter goes into the built manifest, and affects a wide range of
  behavior, so bumping it requires careful testing. This is used
  purely at build time, and should have no effect on runtime
  behavior.

This value needs to be at least as high as targetSdkVersion, and we
need to bump that to 34 soon (zulip#5877). So, do this to prepare for
that.

No build failures or warnings appeared for me with
  tools/test native --all-files
.
chrisbobbe added a commit to chrisbobbe/zulip-mobile that referenced this issue Jul 10, 2024
As we said on the last one of these, fc2dab7:

  This setting is not to be confused with the targetSdkVersion. The
  latter goes into the built manifest, and affects a wide range of
  behavior, so bumping it requires careful testing. This is used
  purely at build time, and should have no effect on runtime
  behavior.

This value needs to be at least as high as targetSdkVersion, and we
need to bump that to 34 soon (zulip#5877). So, do this to prepare for
that.

No build failures or warnings appeared for me with
  tools/test native --all-files
.

Related: zulip#5877
@gnprice
Copy link
Member Author

gnprice commented Jul 10, 2024

showed no problems, which I guess isn't surprising because it's not Android 14.

Yeah — once targetSdkVersion is at least equal to the device's SDK version, it should be completely indifferent to the specific value. So a targetSdkVersion of 34 vs. 33 should mean exactly the same thing to any device with SDK version up through 33, i.e. up through Android 13.

@gnprice
Copy link
Member Author

gnprice commented Jul 10, 2024

Thanks for the detailed read through the breaking-changes page! I'll do a separate read too, for a cross-check.

@gnprice gnprice changed the title Target Android 14 (set targetSdkVersion to 34), by 2023-08 deadline Target Android 14 (set targetSdkVersion to 34), by 2023-10 deadline Aug 2, 2024
@gnprice
Copy link
Member Author

gnprice commented Aug 10, 2024

OK, doing my own read-through. After I read each of these items I'm also going and reading your notes on them — thanks for the thorough validation of where some of these APIs are used!

  • Core functionality

    • Foreground services — I agree, I believe we don't have any.

    • Bluetooth — agree, should be irrelevant

    • OpenJDK 17

      • Regexes — yeah, hopefully nothing has an invalid group reference anyway. If something does, I guess we'll either discover it in manual testing (or users later reporting it as a bug), or it probably isn't commonly enough triggered to worry about.

        FWIW that regex in react-native-webview does have a group reference (the \\1), but it looks perfectly valid (there's a group that comes before it, in fact two such groups; it'll refer to what the (\"?) captured).

      • UUIDs — similar story to the regexes, but UUIDs are less ubiquitous than regexes.

      • ProGuard — yeah agreed, irrelevant to us

    • JobScheduler — I looked in Android Studio at those onStartJob/onStopJob methods; nothing in our project implements the JobService interface they live on. So indeed definitely not using that.

    • Tiles — I looked in Android Studio at that deprecated method startActivityAndCollapse. The only call site was elsewhere in the Android SDK (in com.android.egg.neko.NekoTile); and that class in turn has no references. So indeed definitely not using.

  • Privacy

  • User experience

    • Full-screen intents — agreed, irrelevant
  • Security

    • Implicit intents — We have several intent filters. Some are on exported components (with android:exported="true"), our MainActivity and ShareToZulipActivity; so those are fine. Then some are on unexported components, so any intents targeting those will need to be explicit. Those components are FcmListenerService, matching action com.google.firebase.MESSAGING_EVENT; and com.google.firebase.iid.FirebaseInstanceIdService, matching action com.google.firebase.INSTANCE_ID_EVENT.

      I guess we can validate both of those by making a fresh install, with android: compileSdkVersion to 34 (Android 14) #5879, on an Android 14 device, and verifying that notifications work.

    • Pending intents — I believe we don't ever create a mutable pending intent, so this doesn't affect us. (I looked for references to PendingIntent.FLAG_MUTABLE; there were just a few, I believe all in the Android SDK, and none looking like something we might be indirectly calling. And OTOH the PendingIntent in our notifications uses PendingIntent.FLAG_IMMUTABLE.)

    • Runtime-registered broadcast receivers — we don't use these. Following the link on context-registered receivers, those require androidx.core version 1.9.0+; we're on 1.7.0 and so don't have the ContextCompat.registerReceiver API we'd use in order to make such a thing.

    • Dynamic code loading — pretty sure we don't do this. There's no reason we should; and I also looked for references to the PathClassLoader constructors (the class mentioned in this docs section), and found a handful that were all in the Android SDK and all either looked harmless (because they're loading something from within the APK) or not particularly like something we'd transitively use.

      If we do somehow run into this, it'd probably crash the app, so we'd notice in manual testing.

    • Starting activities from background — I don't think we ever do this.

      I don't think we ever call a method like PendingIntent#send. We do construct a PendingIntent that goes on our notifications, describing how to open the notification — but then IIUC it's the system's notification manager that invokes that PendingIntent, by calling PendingIntent#send or the like.

      I'm pretty sure we never bind a service of another app.

    • Zip path traversal — I don't think we ever open a zip file, except our APK itself.

    • MediaProjection — agreed, we never use this

  • Updated non-SDK restrictions — agreed, we seem to be in the clear


In short:

  • The PhotoPicker situation might be fine after all (though those react-native-image-picker threads are puzzling, then). We'll find out from some manual testing.
  • The restrictions on implicit intents are probably fine. We should confirm by manually testing notifications on a fresh install.
  • The other security changes all appear to be fine.

@gnprice
Copy link
Member Author

gnprice commented Aug 10, 2024

After our experience last year with the doc that's supposed to describe the effects of targetSdkVersion being deficient, I also read through the "Behavior changes: all apps" doc.

  • Core functionality
    • Exact alarms — we don't use these.

    • Context-registered broadcasts queued — I believe this is inconsistent terminology for the same concept as "context-registered receivers", which came up above and I determined we don't use.

      Specifically, the link here for "important broadcasts that are declared in the manifest" goes to a section headed "Manifest-declared receivers". So that demonstrates alternation in terminology between the "broadcast" being declared in place X and the broadcast receiver being declared in place X. I believe the same thing is going on with the idea of a "context-registered broadcast" — partly because I don't have any other ideas what it would mean for a broadcast to be "context-registered".

    • Apps can kill only their own background processes — we don't attempt this.

    • "MTU is set to 517 for the first GATT client requesting an MTU" (yes, that's the heading verbatim) — this is deep inside Bluetooth, which we don't use.

    • New reason an app can be placed in the restricted standby bucket — this looks like potentially it could prevent notifications from appearing if we have repeated ANRs. (Which was already true for some ANRs, but I guess not for Service#onBind ANRs.) Not actionable for us, though. We do have some ANRs for some users; if those start causing notification trouble for users where they weren't before, the realistic fix is to get the new Flutter-based app launched to those users.

    • mlock — It'd be weird for us to be using this, and I doubt we are.

    • cached-app resource usage — I think we're using framework-supported lifecycle APIs, and I doubt we're running afoul of this.

  • User experience
    • Non-dismissable notifications — our notifications are all dismissable.
    • Data safety information — we're already content with the answers we've supplied here.
  • Accessibility
    • Non-linear font scaling — I tried a quick test just now, and generally everything works fine. The only glitch I noticed was the count badge on the DMs icon in the bottom nav bar; but that's a marginal enough feature that I'm OK with it being glitched in this legacy app for some users.
  • Security
    • Minimum installable target API level — As a user I certainly noticed this affecting some other apps, which had been unmaintained for years. Doesn't affect us, though. We've met this threshold since 53970d4 back in 2018, when the Play Store started requiring it.

    • Media owner package names — Hmmm. We do actually use this column, when installing notification sounds, to check if a file was put there by our own app.

      Taking the doc literally, the value would be redacted so we can't see it: our app isn't always visible to other apps (that's true only of some system packages), and we don't request QUERY_ALL_PACKAGES permission.

      OTOH, what they probably mean is actually that it's redacted unless the package is visible to our app. That'd make a lot more sense… and it's what the OWNER_PACKAGE_NAME doc itself says. And an app is always visible to itself, so we're in the clear.

      So I guess we could double-check that with manual testing.

      But… the impact of this is pretty minor at worst, and I'm not sure it has any real user impact at all. It can only matter on first install (or first upgrade from an ancient version with a different notification channel ID); only if there's already a sound on the system with the name of our default notification sound, "Zulip - Chime.m4a"; and only if that sound was in fact placed by a previous install of our app.

      Even then, it'll just cause us to set the notification sound to the copy from within our APK rather than to the copy in the device's shared media storage. So the user should still get the sound — I think the only effect is that if they go to the system's notification settings for the app, and consider changing the sound, they'll miss out on seeing the name of the sound as a hint to make discoverable that we have a couple of other sounds with similar names.

      So in the end I'm content to not investigate.

In short: I think there's nothing further to investigate from that doc.

@gnprice
Copy link
Member Author

gnprice commented Sep 18, 2024

The deadline for this is now just over six weeks away (2024-10-31). The next steps are to try the upgrade and do some manual testing.

gnprice pushed a commit to chrisbobbe/zulip-mobile that referenced this issue Sep 20, 2024
As we said on the last one of these, fc2dab7:

  This setting is not to be confused with the targetSdkVersion. The
  latter goes into the built manifest, and affects a wide range of
  behavior, so bumping it requires careful testing. This is used
  purely at build time, and should have no effect on runtime
  behavior.

This value needs to be at least as high as targetSdkVersion, and we
need to bump that to 34 soon (zulip#5877). So, do this to prepare for
that.

The build warnings change slightly, but the new warnings all seem
acceptable.  Details and discussion starting at:
  zulip#5879 (comment)

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

No branches or pull requests

2 participants