Bug 1568674 Leanplum startup problem in Fennec 68.0 r=VladBaicu
☠☠ backed out by 5604883a769e ☠ ☠
authorAndrei Lazar <andrei.a.lazar@softvision.ro>
Tue, 13 Aug 2019 12:32:49 +0000
changeset 548151 a3d80ef3d9b938722e21ae5745c94d67d4155bed
parent 548150 571878b4a37b955037a9ea55b03e9d8ecc7c2d15
child 548152 1c6fcda381406babb03564e10596258572ba3732
push id11848
push userffxbld-merge
push dateMon, 26 Aug 2019 19:26:25 +0000
treeherdermozilla-beta@9b31bfdfac10 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersVladBaicu
bugs1568674
milestone70.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 1568674 Leanplum startup problem in Fennec 68.0 r=VladBaicu Enabled bidirectional realtime variable updates for production mode. Differential Revision: https://phabricator.services.mozilla.com/D41231
mobile/android/base/java/org/mozilla/gecko/mma/MmaDelegate.java
mobile/android/base/java/org/mozilla/gecko/mma/MmaInterface.java
mobile/android/base/java/org/mozilla/gecko/mma/MmaLeanplumImp.java
mobile/android/thirdparty/com/leanplum/Leanplum.java
mobile/android/thirdparty/com/leanplum/LeanplumCloudMessagingProvider.java
mobile/android/thirdparty/com/leanplum/LeanplumNotificationChannel.java
mobile/android/thirdparty/com/leanplum/LeanplumPushService.java
--- a/mobile/android/base/java/org/mozilla/gecko/mma/MmaDelegate.java
+++ b/mobile/android/base/java/org/mozilla/gecko/mma/MmaDelegate.java
@@ -10,16 +10,17 @@ import android.app.Activity;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
 
 import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.BrowserApp;
 import org.mozilla.gecko.Experiments;
+import org.mozilla.gecko.GeckoSharedPrefs;
 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.activitystream.homepanel.ActivityStreamConfiguration;
 import org.mozilla.gecko.firstrun.PanelConfig;
 import org.mozilla.gecko.fxa.FirefoxAccounts;
@@ -104,16 +105,17 @@ public class MmaDelegate {
         final Map<String, Object> attributes = gatherUserAttributes(activity);
         String deviceId = getDeviceId(activity);
         if (deviceId == null) {
             deviceId = UUID.randomUUID().toString();
             setDeviceId(activity, deviceId);
         }
         mmaHelper.setDeviceId(deviceId);
         PrefsHelper.setPref(GeckoPreferences.PREFS_MMA_DEVICE_ID, deviceId);
+        mmaHelper.setToken(GeckoSharedPrefs.forApp(applicationContext).getString("gcm_token", ""));
         // above two config setup required to be invoked before mmaHelper.init.
         mmaHelper.init(activity, attributes);
 
         if (!PackageUtil.isDefaultBrowser(activity)) {
             mmaHelper.event(MmaDelegate.LAUNCH_BUT_NOT_DEFAULT_BROWSER);
         }
         mmaHelper.event(MmaDelegate.LAUNCH_BROWSER);
 
--- a/mobile/android/base/java/org/mozilla/gecko/mma/MmaInterface.java
+++ b/mobile/android/base/java/org/mozilla/gecko/mma/MmaInterface.java
@@ -27,16 +27,18 @@ public interface MmaInterface {
     void start(Context context);
 
     void event(String mmaEvent);
 
     void event(String mmaEvent, double value);
 
     void stop();
 
+    void setToken(String token);
+
     @CheckResult boolean handleGcmMessage(Context context, String from, Bundle bundle);
 
     void setDeviceId(@NonNull String deviceId);
 
     PanelConfig getPanelConfig(@NonNull Context context, PanelConfig.TYPE panelConfigType, final boolean useLocalValues);
 
     void listenOnceForVariableChanges(@NonNull final MmaDelegate.MmaVariablesChangedListener listener);
 }
--- a/mobile/android/base/java/org/mozilla/gecko/mma/MmaLeanplumImp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/mma/MmaLeanplumImp.java
@@ -156,16 +156,21 @@ public class MmaLeanplumImp implements M
     }
 
     @Override
     public void setDeviceId(@NonNull String deviceId) {
         Leanplum.setDeviceId(deviceId);
     }
 
     @Override
+    public void setToken(@NonNull String token) {
+        Leanplum.setToken(token);
+    }
+
+    @Override
     public PanelConfig getPanelConfig(@NonNull Context context, PanelConfig.TYPE type, final boolean useLocalValues) {
         if (useLocalValues) {
             throw new UnsupportedOperationException("Cannot build remote panel config with local values");
         }
 
         switch (type) {
             case WELCOME:
                 return new PanelConfig(type, useLocalValues, LeanplumVariables.welcomePanelTitle, LeanplumVariables.welcomePanelMessage,
--- a/mobile/android/thirdparty/com/leanplum/Leanplum.java
+++ b/mobile/android/thirdparty/com/leanplum/Leanplum.java
@@ -99,16 +99,17 @@ public class Leanplum {
           new ArrayList<>();
   private static final Object heartbeatLock = new Object();
   private static final String LEANPLUM_NOTIFICATION_CHANNEL =
       "com.leanplum.LeanplumNotificationChannel";
   private static RegisterDeviceCallback registerDeviceHandler;
   private static RegisterDeviceFinishedCallback registerDeviceFinishedHandler;
   private static LeanplumDeviceIdMode deviceIdMode = LeanplumDeviceIdMode.MD5_MAC_ADDRESS;
   private static String customDeviceId;
+  private static String customToken;
   private static String defaultChannelId;
   private static boolean userSpecifiedDeviceId;
   private static boolean initializedMessageTemplates = false;
   private static boolean locationCollectionEnabled = true;
   private static ScheduledExecutorService heartbeatExecutor = null;
   private static Context context;
 
   private static Runnable pushStartCallback;
@@ -168,16 +169,20 @@ public class Leanplum {
    * @param enabled Setting this to false will reduce startup latency in development mode, but it's
    * possible that Leanplum will always have the most up-to-date versions of your resources.
    * (Default: true)
    */
   public static void setFileHashingEnabledInDevelopmentMode(boolean enabled) {
     Constants.hashFilesToDetermineModifications = enabled;
   }
 
+  public static void setToken(String token) {
+    customToken = token;
+  }
+
   /**
    * Optional. Whether to enable file uploading in development mode.
    *
    * @param enabled Whether or not files should be uploaded. (Default: true)
    */
   public static void setFileUploadingEnabledInDevelopmentMode(boolean enabled) {
     Constants.enableFileUploadingInDevelopmentMode = enabled;
   }
@@ -629,21 +634,17 @@ public class Leanplum {
     countAggregator.incrementCount("start_with_user_id");
   }
 
   /**
    * Checks for leanplum notifications modules and if someone present - invoke onStart method.
    */
   private static void checkAndStartNotificationsModules() {
     if (Util.hasPlayServices()) {
-      try {
-        Class.forName(LEANPLUM_PUSH_SERVICE).getDeclaredMethod("onStart")
-            .invoke(null);
-      } catch (Throwable ignored) {
-      }
+      LeanplumPushService.onStart();
     } else {
       Log.i("No valid Google Play Services APK found.");
     }
   }
 
   private static void startHelper(
       String userId, final Map<String, ?> attributes, final boolean isBackground) {
     LeanplumEventDataManager.init(context);
@@ -691,16 +692,18 @@ public class Leanplum {
     }
     params.put(Constants.Params.VERSION_NAME, versionName);
     params.put(Constants.Params.DEVICE_NAME, Util.getDeviceName());
     params.put(Constants.Params.DEVICE_MODEL, Util.getDeviceModel());
     params.put(Constants.Params.DEVICE_SYSTEM_NAME, Util.getSystemName());
     params.put(Constants.Params.DEVICE_SYSTEM_VERSION, Util.getSystemVersion());
     if (!TextUtils.isEmpty(registrationId)) {
       params.put(Constants.Params.DEVICE_PUSH_TOKEN, registrationId);
+    } else if (!TextUtils.isEmpty(customToken)) {
+      params.put(Constants.Params.DEVICE_PUSH_TOKEN, customToken);
     }
     params.put(Constants.Keys.TIMEZONE, localTimeZone.getID());
     params.put(Constants.Keys.TIMEZONE_OFFSET_SECONDS, Integer.toString(timezoneOffsetSeconds));
     params.put(Constants.Keys.LOCALE, Util.getLocale());
     params.put(Constants.Keys.COUNTRY, Constants.Values.DETECT);
     params.put(Constants.Keys.REGION, Constants.Values.DETECT);
     params.put(Constants.Keys.CITY, Constants.Values.DETECT);
     params.put(Constants.Keys.LOCATION, Constants.Values.DETECT);
@@ -843,20 +846,18 @@ public class Leanplum {
                   Constants.Keys.DEFAULT_NOTIFICATION_CHANNEL);
 
               if (notificationChannels == null && (defaultNotificationChannel == null
                       || defaultNotificationChannel.isEmpty())) {
                 defaultNotificationChannel = getDefaultChannelId();
               }
 
               try {
-                Class.forName(LEANPLUM_NOTIFICATION_CHANNEL)
-                    .getDeclaredMethod("configureChannels", Context.class, JSONArray.class,
-                        JSONArray.class, String.class).invoke(new Object(), context,
-                    notificationGroups, notificationChannels, defaultNotificationChannel);
+                LeanplumNotificationChannel.configureChannels(context, notificationGroups,
+                        notificationChannels, defaultNotificationChannel);
               } catch (Throwable ignored) {
               }
             }
 
             String token = response.optString(Constants.Keys.TOKEN, null);
             RequestOld.setToken(token);
             RequestOld.saveToken();
 
@@ -875,18 +876,16 @@ public class Leanplum {
 
             Set<String> enabledCounters = parseSdkCounters(response);
             countAggregator.setEnabledCounters(enabledCounters);
             Set<String> enabledFeatureFlags = parseFeatureFlags(response);
             FeatureFlagManager.INSTANCE.setEnabledFeatureFlags((enabledFeatureFlags));
             parseVariantDebugInfo(response);
 
             // Allow bidirectional realtime variable updates.
-            if (Constants.isDevelopmentModeEnabled) {
-
               final Context currentContext = (
                   LeanplumActivityHelper.currentActivity != context &&
                       LeanplumActivityHelper.currentActivity != null) ?
                   LeanplumActivityHelper.currentActivity
                   : context;
 
               // Register device.
               if (!response.optBoolean(
@@ -935,17 +934,17 @@ public class Leanplum {
                   }
                 });
               }
 
               boolean isRegistered = response.optBoolean(Constants.Keys.IS_REGISTERED);
 
               // Check for updates.
               final String latestVersion = response.optString(Constants.Keys.LATEST_VERSION, null);
-              if (isRegistered && latestVersion != null) {
+              if (isRegistered && latestVersion != null && Constants.isDevelopmentModeEnabled) {
                 Log.i("An update to Leanplum Android SDK, " + latestVersion +
                     ", is available. Go to leanplum.com to download it.");
               }
 
               JSONObject valuesFromCode = response.optJSONObject(Constants.Keys.VARS_FROM_CODE);
               if (valuesFromCode == null) {
                 valuesFromCode = new JSONObject();
               }
@@ -964,17 +963,16 @@ public class Leanplum {
               VarCache.setDevModeValuesFromServer(
                   JsonConverter.mapFromJson(valuesFromCode),
                   JsonConverter.mapFromJson(fileAttributes),
                   JsonConverter.mapFromJson(actionDefinitions));
 
               if (isRegistered) {
                 LeanplumInternal.onHasStartedAndRegisteredAsDeveloper();
               }
-            }
             LeanplumInternal.moveToForeground();
             startHeartbeat();
           } catch (Throwable t) {
             Util.handleException(t);
           }
         }
         return null;
       }
--- a/mobile/android/thirdparty/com/leanplum/LeanplumCloudMessagingProvider.java
+++ b/mobile/android/thirdparty/com/leanplum/LeanplumCloudMessagingProvider.java
@@ -84,24 +84,18 @@ abstract class LeanplumCloudMessagingPro
    * @param registrationId Registration Id.
    */
   void onRegistrationIdReceived(Context context, String registrationId) {
     if (registrationId == null) {
       Log.w("Registration ID is undefined.");
       return;
     }
     LeanplumCloudMessagingProvider.registrationId = registrationId;
-    // Check if received push notification token is different from stored one and send new one to
-    // server.
-    if (!LeanplumCloudMessagingProvider.registrationId.equals(SharedPreferencesUtil.getString(
-        context, Constants.Defaults.LEANPLUM_PUSH, Constants.Defaults.PROPERTY_REGISTRATION_ID))) {
-      Log.i("Device registered for push notifications with registration token", registrationId);
-      storePreferences(context.getApplicationContext());
-      sendRegistrationIdToBackend(LeanplumCloudMessagingProvider.registrationId);
-    }
+    storePreferences(context.getApplicationContext());
+    sendRegistrationIdToBackend(registrationId);
   }
 
   /**
    * Stores the registration ID in the application's {@code SharedPreferences}.
    *
    * @param context The application context.
    */
   public void storePreferences(Context context) {
--- a/mobile/android/thirdparty/com/leanplum/LeanplumNotificationChannel.java
+++ b/mobile/android/thirdparty/com/leanplum/LeanplumNotificationChannel.java
@@ -626,17 +626,17 @@ class LeanplumNotificationChannel {
    * Configure groups, channels, default channel for application. This method will call by
    * reflection from AndroidSDKCore.
    *
    * @param context The application context.
    * @param notificationGroups Notification groups.
    * @param notificationChannels Notification channels.
    * @param defaultNotificationChannel Default channel details.
    */
-  static void configureChannels(Context context, JSONArray notificationGroups,
+  public static void configureChannels(Context context, JSONArray notificationGroups,
       JSONArray notificationChannels, String defaultNotificationChannel) {
     // Configure notification channels and groups
     configureNotificationGroups(
         context, notificationGroups);
     configureNotificationChannels(
         context, notificationChannels);
     configureDefaultNotificationChannel(
         context, defaultNotificationChannel);
--- a/mobile/android/thirdparty/com/leanplum/LeanplumPushService.java
+++ b/mobile/android/thirdparty/com/leanplum/LeanplumPushService.java
@@ -104,23 +104,17 @@ public class LeanplumPushService {
   /**
    * Sets the Google Cloud Messaging sender ID. Required for push GCM notifications to work.
    *
    * @param senderId The GCM sender ID to permit notifications from. Use {@link
    * LeanplumPushService#LEANPLUM_SENDER_ID} to use the built-in sender ID for GCM. If you have
    * multiple sender IDs, use {@link LeanplumPushService#setGcmSenderIds}.
    */
   public static void setGcmSenderId(String senderId) {
-    try {
-      Class.forName(COM_LEANPLUM_GCM_PROVIDER).getDeclaredMethod("setSenderId",
-          String.class).invoke(new Object(), senderId);
-    } catch (Throwable throwable) {
-      Log.e("Couldn't invoke a LeanplumGcmProvider.setGcmSenderId method, please be " +
-          "sure you include LeanplumGCM module.", throwable);
-    }
+    LeanplumGcmProvider.setSenderId(senderId);
   }
 
   /**
    * Sets the Google Cloud Messaging sender ID. Required for push GCM notifications to work.
    *
    * @param senderIds The GCM sender IDs to permit notifications from. Use {@link
    * LeanplumPushService#LEANPLUM_SENDER_ID} to use the built-in sender ID.
    */
@@ -739,49 +733,17 @@ public class LeanplumPushService {
   public static void setGcmRegistrationId(String token) {
     new LeanplumManualProvider(Leanplum.getContext().getApplicationContext(), token);
   }
 
   /**
    * Call this when Leanplum starts. This method will call by reflection from AndroidSDKCore.
    */
   static void onStart() {
-    Class leanplumGcmPushServiceClass = null;
-    Class leanplumFcmPushServiceClass = null;
-
-    try {
-      leanplumGcmPushServiceClass = Class.forName(LEANPLUM_PUSH_SERVICE_GCM);
-    } catch (Throwable ignored) {
-    }
-
-    try {
-      leanplumFcmPushServiceClass = Class.forName(LEANPLUM_PUSH_SERVICE_FCM);
-    } catch (Throwable ignored) {
-    }
-
-    if (leanplumGcmPushServiceClass != null && leanplumFcmPushServiceClass != null) {
-      Log.e("Leanplum does not support leanplum-gcm and leanplum-fcm library at the " +
-          "same time. To support Leanplum GCM and Location services modify your build.gradle by " +
-          "including only implementation 'com.leanplum:leanplum:+' " +
-          "To support only GCM services, use implementation 'com.leanplum:leanplum-gcm:+' " +
-          "For FCM services include implementation 'com.leanplum:leanplum-fcm:+'" +
-          " If you wish to use Leanplum FCM and Location services you also need to include " +
-          "implementation 'com.leanplum:leanplum-location:+'.");
-
-    } else if (leanplumGcmPushServiceClass != null) {
-      try {
-        leanplumGcmPushServiceClass.getDeclaredMethod("onStart").invoke(null);
-      } catch (Throwable ignored) {
-      }
-    } else if (leanplumFcmPushServiceClass != null) {
-      try {
-        leanplumFcmPushServiceClass.getDeclaredMethod("onStart").invoke(null);
-      } catch (Throwable ignored) {
-      }
-    }
+      LeanplumPushServiceGcm.onStart();
   }
 
   /**
    * Initialize push service.
    */
   static void initPushService() {
     if (!provider.isInitialized() || !provider.isManifestSetup()) {
       return;