Bug 1505685 - Part 1 - Register PackageAddedReceiver on the main thread; r=JanH
☠☠ backed out by 86d8ead0b9a5 ☠ ☠
authorPetru Lingurar <petru.lingurar@softvision.ro>
Wed, 21 Nov 2018 11:18:41 +0200
changeset 503947 9344087c8d8e0b6a2874d18684c01ffb49f6bdcd
parent 503875 0119ff5d4de90ac8c66397721aacb91beb8f6756
child 503948 a46710b7723fc89bc3e51b437d59f5c169bab1f6
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersJanH
bugs1505685
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1505685 - Part 1 - Register PackageAddedReceiver on the main thread; r=JanH Summary: Speculative fix for avoiding the situation in which the initialization of Mma and registering of the PackageAddedReceiver continues on the background thread after BrowserApp is destroyed and calls for unregistering the receiver. By registering the receiver on the main thread we have the benefit of sequentially execution which would guarantee that the registration is done before trying to unregister it. Reviewers: JanH Reviewed By: JanH Bug #: 1505685 Differential Revision: https://phabricator.services.mozilla.com/D12031
mobile/android/base/java/org/mozilla/gecko/mma/MmaDelegate.java
--- a/mobile/android/base/java/org/mozilla/gecko/mma/MmaDelegate.java
+++ b/mobile/android/base/java/org/mozilla/gecko/mma/MmaDelegate.java
@@ -79,16 +79,21 @@ public class MmaDelegate {
 
     private static final MmaInterface mmaHelper = MmaConstants.getMma();
     private static Context applicationContext;
     private static PackageAddedReceiver packageAddedReceiver;
     private static String activityName;     // used to retrieve Activity's SharedPreferences
 
     public static void init(final Activity activity,
                             final MmaVariablesChangedListener remoteVariablesListener) {
+        ThreadUtils.postToUiThread(() -> {
+            if (isActivityAlive(activity)) {
+                registerInstalledPackagesReceiver(activity);
+            }
+        });
         applicationContext = activity.getApplicationContext();
         // Since user attributes are gathered in Fennec, not in MMA implementation,
         // we gather the information here then pass to mmaHelper.init()
         // Note that generateUserAttribute always return a non null HashMap.
         final Map<String, Object> attributes = gatherUserAttributes(activity);
         final String deviceId = getDeviceId(activity);
         mmaHelper.setDeviceId(deviceId);
         PrefsHelper.setPref(GeckoPreferences.PREFS_MMA_DEVICE_ID, deviceId);
@@ -96,17 +101,16 @@ public class MmaDelegate {
         mmaHelper.init(activity, attributes);
 
         if (!isDefaultBrowser(activity)) {
             mmaHelper.event(MmaDelegate.LAUNCH_BUT_NOT_DEFAULT_BROWSER);
         }
         mmaHelper.event(MmaDelegate.LAUNCH_BROWSER);
 
         activityName = activity.getLocalClassName();
-        registerInstalledPackagesReceiver(activity);
         notifyAboutPreviouslyInstalledPackages(activity);
 
         ThreadUtils.postToUiThread(new Runnable() {
             @Override
             public void run() {
                 mmaHelper.listenOnceForVariableChanges(remoteVariablesListener);
             }
         });
@@ -295,28 +299,40 @@ public class MmaDelegate {
 
     private static void registerInstalledPackagesReceiver(@NonNull final Activity activity) {
         packageAddedReceiver = new PackageAddedReceiver();
         activity.registerReceiver(packageAddedReceiver, PackageAddedReceiver.getIntentFilter());
     }
 
     private static void unregisterInstalledPackagesReceiver(@NonNull final Activity activity) {
         if (packageAddedReceiver != null) {
-            try {
-                // TODO investigate why the receiver would not be registered - bug 1505685
-                activity.unregisterReceiver(packageAddedReceiver);
-            } catch (IllegalArgumentException e) {
-                if (AppConstants.RELEASE_OR_BETA) {
-                    Log.w(TAG, "bug 1505685", e);
-                } else {
-                   throw e;
-                }
-            }
+            activity.unregisterReceiver(packageAddedReceiver);
             packageAddedReceiver = null;
         }
     }
 
+    /**
+     * Check and return if the Activity is still alive.
+     *
+     * @param activity an instance of {@link Activity} to be checked if it is still alive.<br>
+     *                 Might be an already leaked instance.
+     * @return <code>true</code> if the Activity is still alive;<br>
+     *         <code>false</code> if the Activity is destroyed / in the process of being destroyed.
+     * @throws IllegalThreadStateException
+     *         if {@link AppConstants#RELEASE_OR_BETA} and called on another thread than Main
+     */
+    private static boolean isActivityAlive(@NonNull final Activity activity) throws IllegalThreadStateException {
+        // all lifecycle methods are run on Main
+        ThreadUtils.assertOnUiThread();
+
+        if (activity.isFinishing()) {
+            return false;
+        }
+
+        return true;
+    }
+
     public interface MmaVariablesChangedListener {
         void onRemoteVariablesChanged();
 
         void onRemoteVariablesUnavailable();
     }
 }