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

Feature: IN-APP UPDATES #20822

Merged
merged 54 commits into from
May 20, 2024
Merged

Feature: IN-APP UPDATES #20822

merged 54 commits into from
May 20, 2024

Conversation

pantstamp
Copy link
Contributor

@pantstamp pantstamp commented May 15, 2024

This PR implements the In-app updates feature on Android.

More details about Google's in-app updates can be found here. Please read the contents of the link first to get more context. We use the Google Play Core libraries to support UX flows for in-app updates, allowing users to keep our app up to date on their devices.

To Test:

Testing this feature requires many steps. We need to test both the "immediate update" flow and the "flexible update" flow.

When an update is available, we need to decide which flow to use. We utilize a remote config value from the backend representing the last version of our app that requires an immediate update. This is usually a version that contains a critical bug fix or a new feature that our app cannot function properly without. If the current version of the installed app on the user's device is lower than the remote config value, then the immediate update flow is launched. Otherwise, we go with the flexible one.

ATTENTION: The current remote config value is 80000. This means that when you try to update a version of the app that is < 80000, the immediate flow will be launched.

To test this feature, we use Internal app sharing as Google suggests here.

Please read how Internal app sharing works here.

ATTENTION: As app bundle links in Internal app sharing might expire, you may need to reupload an app bundle to get a new link to use. The page for uploading is here. If you have the Release apps to testing tracks permission, you’re authorized to upload app bundles and APKs for internal sharing by default. If you don't, you can make a request in Systems P2 like this.

  1. Enable internal app sharing on your device following the instructions:
Open the Google Play Store app Google Play.
Tap Menu Menu > Settings.
In the "About" section, tap the Play Store version 7 times.
After the Internal app sharing setting appears, tap the switch to turn on internal app sharing.
Tap Turn on.  
  1. Download the 3 app versions on your computer. Having these versions on your machine will allow you to reupload them as many times as you want and get new links if the old ones have expired. Link here. Upload the 3 files using the page for uploading. Get the 3 links and send them to your device so you can tap on them from there (You could send the links with an email).
  2. Uninstall all versions of the Jetpack app that you have on your device.
  3. Tap on the first link for version 79999.
  4. A Google Play page appears. Tap on the "Install" button. When the download is over, tap on "Open".
  5. Login with a non-automattic account.
  6. From your device, tap the second link for version 80000. You will see a page with an "Update" button. DO NOT tap on it and go back to the app.
  • Check that nothing happens and no update is shown.
  1. Tap on "Me" button in the bottom navigation bar and tap on "Debug settings".
  2. Enable "in app updates" FF.
  3. Kill and restart the app.
  • Check that a full screen appears for the "immediate" update.
  • Check that the IN_APP_UPDATE_SHOWN event is tracked.
    Screenshot_20240517-125236
  1. Tap on the X button on the top right corner to dismiss it.
  • Check that when close and relaunch the no update screen appears
  • Check that the IN_APP_UPDATE_DISMISSED event is tracked.
  1. Wait for 5 minutes or more.
  2. Launch the app.
  • Check that the Update screen reappears.
  1. Tap on Update button.
  • Check that a full screen appears from Google Play lib showing the download progress and then installs the update. When the update is installed the app is relaunched.
  • Check that the version of the app is 80000 now.
  1. Go and tap the link for version 80001 on your device. You can see a page with an "Update" button. DO NOT tap on it and go back to the app.
  • Check that a bottom sheet appears about the update.
  • Check that the IN_APP_UPDATE_SHOWN event is tracked
  1. Tap on the "X" button of the bottom sheet.
  • Check that the IN_APP_UPDATE_DISMISSED event is tracked
  • Check that when you restart the app or put it in the background and then relaunch it, no update bottom sheet appears. (This is because there is an interval of how often a flexible update can appear so we won't annoy our users. This is defined by a remote config and its current value is 5 days.)
  1. Clear the data of the app, login again, and enable in-app-updates FF.
  2. Kill and restart the app.
  • Check that the update bottom sheet appears.
  1. Tap "Update" button.
  • Check that the IN_APP_UPDATE_ACCEPTED event is tracked.
  • Check that the update is downloading in the background.
  1. When the update is downloaded and our app is in the foreground:
  • Check that a snackbar appears that informs the user and asking for a restart.
  1. Tap on the restart action.
  • Check that the IN_APP_UPDATE_COMPLETED_WITH_APP_RESTART event is tracked.
  • Check that the update is installed and the app is restarted.

Attention: If the app is in the background when the update is downloaded, the update is installed silently without notifying the user.

Please feel free to explore unhappy paths, like turning off the internet connection while an update is being downloaded and then trying to restart the app.


Regression Notes

  1. Potential unintended areas of impact

    • N/A
  2. What I did to test those areas of impact (or what existing automated tests I relied on)

    • Manual testing and unit tests.
  3. What automated tests I added (or what prevented me from doing so)

    • N/A

PR Submission Checklist:

  • I have completed the Regression Notes.
  • I have considered adding accessibility improvements for my changes.
  • I have considered if this change warrants user-facing release notes and have added them to RELEASE-NOTES.txt if necessary.

Testing Checklist (strike-out the not-applying and unnecessary ones):

  • WordPress.com sites and self-hosted Jetpack sites.
  • Portrait and landscape orientations.
  • Light and dark modes.
  • Fonts: Larger, smaller and bold text.
  • High contrast.
  • Talkback.
  • Languages with large words or with letters/accents not frequently used in English.
  • Right-to-left languages. (Even if translation isn’t complete, formatting should still respect the right-to-left layout)
  • Large and small screen sizes. (Tablet and smaller phones)
  • Multi-tasking: Split screen and Pop-up view. (Android 10 or higher)

AjeshRPai and others added 30 commits March 23, 2023 09:40
Moves: the dependency version and implementation code change
for better dependency management visibility
# Conflicts:
#	WordPress/src/main/java/org/wordpress/android/modules/ApplicationModule.java
#	WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java
#	WordPress/src/main/res/values/strings.xml
#	build.gradle
#	version.properties
# Conflicts:
#	WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java
#	version.properties
# Conflicts:
#	WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java
#	version.properties
@pantstamp pantstamp requested a review from AjeshRPai May 15, 2024 14:45
@dangermattic
Copy link
Collaborator

dangermattic commented May 15, 2024

3 Warnings
⚠️ strings.xml files should only be updated on release branches, when the translations are downloaded by our automation.
⚠️ This PR is larger than 300 lines of changes. Please consider splitting it into smaller PRs for easier and faster reviews.
⚠️ Class InAppUpdateManagerNoop is missing tests, but unit-tests-exemption label was set to ignore this.

Generated by 🚫 Danger

@wpmobilebot
Copy link
Contributor

Found 1 violations:

The PR caused some dependency changes (expand to see details)

++--- com.google.android.play:app-update:2.1.0
+|    +--- com.google.android.gms:play-services-basement:18.1.0 -> 18.2.0 (*)
+|    +--- com.google.android.gms:play-services-tasks:18.0.2 (*)
+|    \--- com.google.android.play:core-common:2.0.3
++--- com.google.android.play:app-update-ktx:2.1.0
+|    +--- androidx.core:core:1.1.0 -> 1.12.0 (*)
+|    +--- androidx.fragment:fragment:1.1.0 -> 1.6.2 (*)
+|    +--- com.google.android.gms:play-services-basement:18.1.0 -> 18.2.0 (*)
+|    +--- com.google.android.gms:play-services-tasks:18.0.2 (*)
+|    +--- com.google.android.play:app-update:2.1.0 (*)
+|    +--- com.google.android.play:core-common:2.0.3
+|    +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72 -> 1.9.10 (*)
+|    +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0 -> 1.7.3 (*)
+|    \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0 -> 1.7.3 (*)
 +--- com.google.android.play:review:2.0.1
-|    \--- com.google.android.play:core-common:2.0.2
+|    \--- com.google.android.play:core-common:2.0.2 -> 2.0.3

Please review and act accordingly

@wpmobilebot
Copy link
Contributor

wpmobilebot commented May 15, 2024

WordPress📲 You can test the changes from this Pull Request in WordPress by scanning the QR code below to install the corresponding build.
App NameWordPress WordPress
FlavorJalapeno
Build TypeDebug
Versionpr20822-c138065
Commitc138065
Direct Downloadwordpress-prototype-build-pr20822-c138065.apk
Note: Google Login is not supported on these builds.

@wpmobilebot
Copy link
Contributor

wpmobilebot commented May 15, 2024

Jetpack📲 You can test the changes from this Pull Request in Jetpack by scanning the QR code below to install the corresponding build.
App NameJetpack Jetpack
FlavorJalapeno
Build TypeDebug
Versionpr20822-c138065
Commitc138065
Direct Downloadjetpack-prototype-build-pr20822-c138065.apk
Note: Google Login is not supported on these builds.

Copy link

codecov bot commented May 15, 2024

Codecov Report

Attention: Patch coverage is 56.58915% with 56 lines in your changes are missing coverage. Please review.

Project coverage is 40.69%. Comparing base (16ffc05) to head (c138065).
Report is 40 commits behind head on trunk.

Files Patch % Lines
...ress/android/inappupdate/InAppUpdateManagerImpl.kt 65.55% 19 Missing and 12 partials ⚠️
...rdpress/android/inappupdate/InAppUpdateListener.kt 0.00% 7 Missing ⚠️
...ress/android/inappupdate/InAppUpdateManagerNoop.kt 0.00% 5 Missing ⚠️
...rdpress/android/util/config/RemoteConfigWrapper.kt 0.00% 5 Missing ⚠️
...id/util/config/InAppUpdateBlockingVersionConfig.kt 0.00% 3 Missing ⚠️
...d/util/config/InAppUpdateFlexibleIntervalConfig.kt 0.00% 3 Missing ⚠️
...rdpress/android/inappupdate/IInAppUpdateManager.kt 0.00% 1 Missing ⚠️
...android/inappupdate/InAppUpdateAnalyticsTracker.kt 90.90% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##            trunk   #20822      +/-   ##
==========================================
+ Coverage   40.66%   40.69%   +0.03%     
==========================================
  Files        1490     1498       +8     
  Lines       68629    68757     +128     
  Branches    11340    11364      +24     
==========================================
+ Hits        27911    27984      +73     
- Misses      38198    38241      +43     
- Partials     2520     2532      +12     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@pantstamp pantstamp requested a review from zwarm May 17, 2024 15:04
@pantstamp pantstamp added this to the 25.0 milestone May 17, 2024
@pantstamp pantstamp marked this pull request as ready for review May 17, 2024 15:06
@pantstamp pantstamp changed the title IN-APP UPDATES Feature: IN-APP UPDATES May 17, 2024
Copy link
Contributor

@AjeshRPai AjeshRPai left a comment

Choose a reason for hiding this comment

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

Hey @pantstamp
Awesome job on integrating the api to the app.

Overall the flow looks good to me. I tested both the flows (immediate and flexible) and it looks good to me. Also I tested the tracking logic which I think we should add to the PR testing instructions so that we are on the same page.

Things I noticed while testing the flow.

  1. During the flexible update flow a snackbar is shown with Restart action when the download is completed.
    There was no tracking for clicking on this snackbar action button. I think its good to have a tracking there as well.

  2. During the immediate update flow
    After clicking accepted on the update modal, I couldn't see the tracking in the log console. But I couldn't test it again as the link for the first uploaded app version(79999) is returning error after I updated the app to 8000000. I tried re-uploading the 799999 and retrying the workflow but it didn't work. If you can confirm there is tracking on accepting the update on the immediate update flow. You can go ahead and do the merge.

@Override public void onAppUpdateDownloaded() {
popupSnackbarForCompleteUpdate();
}
@Override public void onAppUpdateStarted(int type) {
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 need all these callbacks on the interface and the listener if we are not using them?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice catch here @AjeshRPai ! I want to keep the callbacks in case we need them for a future "client". I proceeded with a small refactoring, providing default empty implementations, so each client will be able to implement only the callbacks they need.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks Makes sense

@pantstamp
Copy link
Contributor Author

@AjeshRPai thank you for reviewing the PR! I will reply to all of your comments as I address them 🙌

@pantstamp
Copy link
Contributor Author

@AjeshRPai added analytics event for app restart -> IN_APP_UPDATE_COMPLETED_WITH_APP_RESTART

@pantstamp
Copy link
Contributor Author

@AjeshRPai, I can confirm that no tracking is logged for accepting the update in the "Immediate" flow. I intended to add this as a "known issue," but I forgot. Thanks for reminding me!

I tried to make this work but without success. The problem lies in the fact that in the immediate flow, when the full-screen modal appears and the user accepts the update, the flow of execution never returns to our app until the install is complete and the app is restarted. So our activity's onResult is never called.

We could calculate this number by using: trackUpdateShown(AppUpdateType.IMMEDIATE) - trackUpdateDismissed(AppUpdateType.IMMEDIATE).

Copy link

sonarcloud bot commented May 20, 2024

Quality Gate Passed Quality Gate passed

Issues
3 New issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
0.0% Duplication on New Code

See analysis details on SonarCloud

@AjeshRPai
Copy link
Contributor

@pantstamp

he problem lies in the fact that in the immediate flow, when the full-screen modal appears and the user accepts the update, the flow of execution never returns to our app until the install is complete and the app is restarted. So our activity's onResult is never called.

Got it Pantelis. I thought this would be the case.

You can go ahead and merge the PR

@pantstamp pantstamp merged commit 595f399 into trunk May 20, 2024
18 checks passed
@pantstamp pantstamp deleted the pantelis/in-app-updates branch May 20, 2024 13:08
Copy link

sentry-io bot commented May 22, 2024

Suspect Issues

This pull request was deployed and Sentry observed the following issues:

  • ‼️ ApplicationNotResponding: Background ANR org.wordpress.android.util.config.RemoteConfigW... View Issue

Did you find this useful? React with a 👍 or 👎

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

5 participants