Bug 1396548 - Handle Push Notification when app is not running. r=maliu
authorNevin Chen <cnevinchen@gmail.com>
Mon, 04 Sep 2017 19:15:32 +0800
changeset 378827 079ab757385041449d680ead8127a6efd6febdbb
parent 378826 c46043dc11c635f8180d8f4a80b7c5a35522e89c
child 378828 cc5f0a6017a13554e441b1a5002aa4191e7c9de1
push id32442
push userarchaeopteryx@coole-files.de
push dateTue, 05 Sep 2017 09:39:11 +0000
treeherdermozilla-central@35bd47b6e5ac [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmaliu
bugs1396548
milestone57.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 1396548 - Handle Push Notification when app is not running. r=maliu When app is not runing, Gecko is not running. Thus we can't get Gecko pref. We should skip Gecko pref check and show notifications when we recieve push messages and while app is not running. Other checks (ie. Switchboard, Health Report...etc) remain the same. MozReview-Commit-ID: H2X18VI0cnW
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
@@ -13,16 +13,17 @@ import android.content.pm.PackageManager
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
 import android.text.TextUtils;
 import android.util.Log;
 
 import org.mozilla.gecko.Experiments;
+import org.mozilla.gecko.GeckoThread;
 import org.mozilla.gecko.MmaConstants;
 import org.mozilla.gecko.PrefsHelper;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.Tab;
 import org.mozilla.gecko.Tabs;
 import org.mozilla.gecko.fxa.FirefoxAccounts;
 import org.mozilla.gecko.preferences.GeckoPreferences;
 import org.mozilla.gecko.push.PushManager;
@@ -59,16 +60,17 @@ public class MmaDelegate {
     public static final String PACKAGE_NAME_FOCUS = "org.mozilla.focus";
     public static final String PACKAGE_NAME_POCKET = "com.ideashower.readitlater.pro";
 
     private static final String TAG = "MmaDelegate";
     private static final String KEY_PREF_BOOLEAN_MMA_ENABLED = "mma.enabled";
     private static final String[] PREFS = { KEY_PREF_BOOLEAN_MMA_ENABLED };
 
 
+    @Deprecated
     private static boolean isGeckoPrefOn = false;
     private static MmaInterface mmaHelper = MmaConstants.getMma();
     private static WeakReference<Context> applicationContext;
 
     public static void init(Activity activity) {
         applicationContext = new WeakReference<>(activity.getApplicationContext());
         setupPrefHandler(activity);
     }
@@ -87,17 +89,16 @@ public class MmaDelegate {
                         // isGeckoPrefOn needs to be set before mmaHelper.init() cause we need it for isMmaEnabled()
                         isGeckoPrefOn = true;
 
                         // 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.
                         Map<String, Object> attributes = gatherUserAttributes(activity);
                         mmaHelper.setGcmSenderId(PushManager.getSenderIds());
-                        mmaHelper.setCustomIcon(R.drawable.ic_status_logo);
                         mmaHelper.init(activity, attributes);
 
                         if (!isDefaultBrowser(activity)) {
                             mmaHelper.event(MmaDelegate.LAUNCH_BUT_NOT_DEFAULT_BROWSER);
                         }
                         mmaHelper.event(MmaDelegate.LAUNCH_BROWSER);
                     } else {
                         isGeckoPrefOn = false;
@@ -118,60 +119,67 @@ public class MmaDelegate {
         attributes.put(USER_ATT_KLAR_INSTALLED, ContextUtils.isPackageInstalled(context, PACKAGE_NAME_KLAR));
         attributes.put(USER_ATT_POCKET_INSTALLED, ContextUtils.isPackageInstalled(context, PACKAGE_NAME_POCKET));
         attributes.put(USER_ATT_DEFAULT_BROWSER, isDefaultBrowser(context));
         attributes.put(USER_ATT_SIGNED_IN, FirefoxAccounts.firefoxAccountsExist(context));
 
         return attributes;
     }
 
-
     public static void track(String event) {
-        if (isMmaEnabled()) {
+        if (applicationContext != null && isMmaEnabled(applicationContext.get())) {
             mmaHelper.event(event);
         }
     }
 
+
     public static void track(String event, long value) {
-        if (isMmaEnabled()) {
+        if (applicationContext != null && isMmaEnabled(applicationContext.get())) {
             mmaHelper.event(event, value);
         }
     }
 
-    private static boolean isMmaEnabled() {
-        if (applicationContext == null) {
-            return false;
-        }
+    // isMmaEnabled should use pass-in context. The context comes from
+    // 1. track(), it's called from UI (where we inject events). Context is from weak reference to Activity (assigned in init())
+    // 2. handleGcmMessage(), it's called from GcmListenerService (where we handle GCM messages). Context is from the Service
+    private static boolean isMmaEnabled(Context context) {
 
-        final Context context = applicationContext.get();
         if (context == null) {
             return false;
         }
-
         final boolean healthReport = GeckoPreferences.getBooleanPref(context, GeckoPreferences.PREFS_HEALTHREPORT_UPLOAD_ENABLED, true);
         final boolean inExperiment = SwitchBoard.isInExperiment(context, Experiments.LEANPLUM);
         final Tab selectedTab = Tabs.getInstance().getSelectedTab();
-        // if selected tab is null or private, mma should be disabled.
-        final boolean isInPrivateBrowsing = selectedTab == null || selectedTab.isPrivate();
-        return inExperiment && healthReport && isGeckoPrefOn && !isInPrivateBrowsing;
+
+        // if selected tab is private, mma should be disabled.
+        final boolean isInPrivateBrowsing = selectedTab != null && selectedTab.isPrivate();
+        // only check Gecko Pref when Gecko is running
+        // FIXME : Remove isGeckoPrefOn in bug 1396714
+        final boolean skipGeckoPrefCheck = !GeckoThread.isRunning();
+        return inExperiment && (skipGeckoPrefCheck || isGeckoPrefOn) && healthReport && !isInPrivateBrowsing;
     }
 
 
-    public static boolean isDefaultBrowser(Context context) {
+    private static boolean isDefaultBrowser(Context context) {
         final Intent viewIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.mozilla.org"));
         final ResolveInfo info = context.getPackageManager().resolveActivity(viewIntent, PackageManager.MATCH_DEFAULT_ONLY);
         if (info == null) {
             // No default is set
             return false;
         }
-
         final String packageName = info.activityInfo.packageName;
         return (TextUtils.equals(packageName, context.getPackageName()));
     }
 
+    // Always use pass-in context. Do not use applicationContext here. applicationContext will be null if MmaDelegate.init() is not called.
     public static boolean handleGcmMessage(@NonNull Context context, String from, @NonNull Bundle bundle) {
-        return isMmaEnabled() && mmaHelper.handleGcmMessage(context, from, bundle);
+        if (isMmaEnabled(context)) {
+            mmaHelper.setCustomIcon(R.drawable.ic_status_logo);
+            return mmaHelper.handleGcmMessage(context, from, bundle);
+        } else {
+            return false;
+        }
     }
 
     public static String getMmaSenderId() {
         return mmaHelper.getMmaSenderId();
     }
 }