Bug 1374889 - Gather user attributes before MMA inits. r?maliu
MozReview-Commit-ID: 5v28pWzYYWj
--- a/mobile/android/base/java/org/mozilla/gecko/mma/MmaDelegate.java
+++ b/mobile/android/base/java/org/mozilla/gecko/mma/MmaDelegate.java
@@ -7,44 +7,55 @@
package org.mozilla.gecko.mma;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
+import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
import org.mozilla.gecko.Experiments;
import org.mozilla.gecko.MmaConstants;
import org.mozilla.gecko.PrefsHelper;
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.switchboard.SwitchBoard;
+import org.mozilla.gecko.util.ContextUtils;
import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.Map;
public class MmaDelegate {
public static final String READER_AVAILABLE = "E_Reader_Available";
public static final String DOWNLOAD_MEDIA_SAVED_IMAGE = "E_Download_Media_Saved_Image";
public static final String CLEARED_PRIVATE_DATA = "E_Cleared_Private_Data";
public static final String SAVED_BOOKMARK = "E_Saved_Bookmark";
public static final String OPENED_BOOKMARK = "E_Opened_Bookmark";
public static final String INTERACT_WITH_SEARCH_URL_AREA = "E_Interact_With_Search_URL_Area";
public static final String SCREENSHOT = "E_Screenshot";
public static final String SAVED_LOGIN_AND_PASSWORD = "E_Saved_Login_And_Password";
public static final String LAUNCH_BUT_NOT_DEFAULT_BROWSER = "E_Launch_But_Not_Default_Browser";
public static final String NEW_TAB = "E_Opened_New_Tab";
+ public static final String USER_ATT_FOCUS_INSTALLED = "Focus Installed";
+ public static final String USER_ATT_KLAR_INSTALLED = "Klar Installed";
+ public static final String USER_ATT_DEFAULT_BROWSER = "Default Browser";
+ public static final String USER_ATT_SIGNED_IN = "Signed In Sync";
+
+
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 };
private static boolean isGeckoPrefOn = false;
private static MmaInterface mmaHelper = MmaConstants.getMma();
private static WeakReference<Context> applicationContext;
@@ -60,30 +71,51 @@ public class MmaDelegate {
private static void setupPrefHandler(final Activity activity) {
PrefsHelper.PrefHandler handler = new PrefsHelper.PrefHandlerBase() {
@Override
public void prefValue(String pref, boolean value) {
if (pref.equals(KEY_PREF_BOOLEAN_MMA_ENABLED)) {
Log.d(TAG, "prefValue() called with: pref = [" + pref + "], value = [" + value + "]");
if (value) {
- mmaHelper.init(activity);
+
+ // 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.init(activity, attributes);
+
if (!isDefaultBrowser(activity)) {
mmaHelper.event(MmaDelegate.LAUNCH_BUT_NOT_DEFAULT_BROWSER);
}
isGeckoPrefOn = true;
} else {
isGeckoPrefOn = false;
}
}
}
};
PrefsHelper.addObserver(PREFS, handler);
}
+ /* This method must be called at background thread to avoid performance issues in some API level */
+ @NonNull
+ private static Map<String, Object> gatherUserAttributes(final Context context) {
+
+ final Map<String, Object> attributes = new HashMap<>();
+
+ attributes.put(USER_ATT_FOCUS_INSTALLED, ContextUtils.isPackageInstalled(context, "org.mozilla.focus"));
+ attributes.put(USER_ATT_KLAR_INSTALLED, ContextUtils.isPackageInstalled(context, "org.mozilla.klar"));
+ 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()) {
mmaHelper.event(event);
}
}
public static void track(String event, long value) {
@@ -118,10 +150,9 @@ public class MmaDelegate {
// No default is set
return false;
}
final String packageName = info.activityInfo.packageName;
return (TextUtils.equals(packageName, context.getPackageName()));
}
-
}
--- a/mobile/android/base/java/org/mozilla/gecko/mma/MmaInterface.java
+++ b/mobile/android/base/java/org/mozilla/gecko/mma/MmaInterface.java
@@ -4,19 +4,21 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.mma;
import android.app.Activity;
import android.content.Context;
+import java.util.Map;
+
public interface MmaInterface {
- void init(Activity Activity);
+ void init(Activity Activity, Map<String, ?> attributes);
void start(Context context);
void event(String mmaEvent);
void event(String mmaEvent, double value);
void stop();
--- a/mobile/android/base/java/org/mozilla/gecko/mma/MmaLeanplumImp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/mma/MmaLeanplumImp.java
@@ -4,87 +4,60 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.mma;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
import com.leanplum.Leanplum;
import com.leanplum.LeanplumActivityHelper;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.MmaConstants;
-import org.mozilla.gecko.fxa.FirefoxAccounts;
-import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class MmaLeanplumImp implements MmaInterface {
private static final String KEY_ANDROID_PREF_STRING_LEANPLUM_DEVICE_ID = "android.not_a_preference.leanplum.device_id";
@Override
- public void init(final Activity activity) {
+ public void init(final Activity activity, Map<String, ?> attributes) {
if (activity == null) {
return;
}
Leanplum.setApplicationContext(activity.getApplicationContext());
LeanplumActivityHelper.enableLifecycleCallbacks(activity.getApplication());
if (AppConstants.MOZILLA_OFFICIAL) {
Leanplum.setAppIdForProductionMode(MmaConstants.MOZ_LEANPLUM_SDK_CLIENTID, MmaConstants.MOZ_LEANPLUM_SDK_KEY);
} else {
Leanplum.setAppIdForDevelopmentMode(MmaConstants.MOZ_LEANPLUM_SDK_CLIENTID, MmaConstants.MOZ_LEANPLUM_SDK_KEY);
}
- Map<String, Object> attributes = new HashMap<>();
- boolean installedFocus = isPackageInstalled(activity, "org.mozilla.focus");
- boolean installedKlar = isPackageInstalled(activity, "org.mozilla.klar");
- if (installedFocus) {
- attributes.put("Focus Installed", true);
- } else {
- attributes.put("Focus Installed", false);
- }
- if (installedKlar) {
- attributes.put("Klar Installed", true);
- } else {
- attributes.put("Klar Installed", false);
- }
-
-
final SharedPreferences sharedPreferences = activity.getPreferences(0);
String deviceId = sharedPreferences.getString(KEY_ANDROID_PREF_STRING_LEANPLUM_DEVICE_ID, null);
if (deviceId == null) {
deviceId = UUID.randomUUID().toString();
sharedPreferences.edit().putString(KEY_ANDROID_PREF_STRING_LEANPLUM_DEVICE_ID, deviceId).apply();
}
Leanplum.setDeviceId(deviceId);
- if (MmaDelegate.isDefaultBrowser(activity)) {
- attributes.put("Default Browser", true);
+
+ if (attributes != null) {
+ Leanplum.start(activity, attributes);
} else {
- attributes.put("Default Browser", false);
+ Leanplum.start(activity);
}
- // In order to trigger the campaign lazily, you check the account existence as an attribute,
- // not when account login success callback is invoked. Because the attribute update lazily when process start.
- if (FirefoxAccounts.firefoxAccountsExist(activity)) {
- attributes.put("Signed In Sync", true);
- } else {
- attributes.put("Signed In Sync", false);
- }
-
- Leanplum.start(activity, attributes);
-
// this is special to Leanplum. Since we defer LeanplumActivityHelper's onResume call till
// switchboard completes loading. We miss the call to LeanplumActivityHelper.onResume.
// So I manually call it here.
//
// There's a risk that if this is called after activity's onPause(Although I've
// tested it's seems okay). We should require their SDK to separate activity call back with
// SDK initialization and Activity lifecycle in the future.
//
@@ -114,18 +87,9 @@ public class MmaLeanplumImp implements M
}
@Override
public void stop() {
Leanplum.stop();
}
- private static boolean isPackageInstalled(final Context context, String packageName) {
- try {
- PackageManager pm = context.getPackageManager();
- pm.getPackageInfo(packageName, 0);
- return true;
- } catch (PackageManager.NameNotFoundException e) {
- return false;
- }
- }
}
--- a/mobile/android/base/java/org/mozilla/gecko/mma/MmaStubImp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/mma/MmaStubImp.java
@@ -2,23 +2,24 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.mma;
import android.app.Activity;
-import android.app.Application;
import android.content.Context;
+import java.util.Map;
+
public class MmaStubImp implements MmaInterface {
@Override
- public void init(Activity activity) {
+ public void init(Activity activity, Map<String, ?> attributes) {
}
@Override
public void start(Context context) {
}
@@ -31,9 +32,10 @@ public class MmaStubImp implements MmaIn
public void event(String leanplumEvent, double value) {
}
@Override
public void stop() {
}
+
}