Bug 1396548 - Handle Push Notification when app is not running. r?maliu draft
authorNevin Chen <cnevinchen@gmail.com>
Mon, 04 Sep 2017 19:15:32 +0800
changeset 658894 27c06cd721e1f4d398187e866133a027bedfdd59
parent 658422 2873c5ea2337f2c6347b4c5e5c1d32a22399559c
child 658900 c4de3ec210ffcbeed6aa64550676853cbbcf8260
child 659103 cc2314c0e9780219c5b540caff18872ca5b8ded8
push id77922
push userbmo:cnevinchen@gmail.com
push dateTue, 05 Sep 2017 04:56:09 +0000
reviewersmaliu
bugs1396548
milestone57.0a1
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();
     }
 }