Bug 1269734 - Changes based on previous review for campaign ID retrieval r?mcomella
MozReview-Commit-ID: I90Dh3WJzst
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -8,16 +8,18 @@ package org.mozilla.gecko;
import android.Manifest;
import android.app.DownloadManager;
import android.os.Environment;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import org.json.JSONArray;
import org.mozilla.gecko.adjust.AdjustHelperInterface;
+import org.mozilla.gecko.adjust.AttributionHelperListener;
+import org.mozilla.gecko.telemetry.measurements.CampaignIdMeasurements;
import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.DynamicToolbar.VisibilityTransition;
import org.mozilla.gecko.Tabs.TabEvents;
import org.mozilla.gecko.animation.PropertyAnimator;
import org.mozilla.gecko.animation.ViewHelper;
import org.mozilla.gecko.cleanup.FileCleanupController;
import org.mozilla.gecko.db.BrowserContract;
@@ -305,28 +307,25 @@ public class BrowserApp extends GeckoApp
// The animator used to toggle HomePager visibility has a race where if the HomePager is shown
// (starting the animation), the HomePager is hidden, and the HomePager animation completes,
// both the web content and the HomePager will be hidden. This flag is used to prevent the
// race by determining if the web content should be hidden at the animation's end.
private boolean mHideWebContentOnAnimationEnd;
private final DynamicToolbar mDynamicToolbar = new DynamicToolbar();
- // Holding a reference here so that we can pass it to the AdjustHelper.
- private final TelemetryCorePingDelegate mTelemetryCorePingDelegate = new TelemetryCorePingDelegate();
-
private final List<BrowserAppDelegate> delegates = Collections.unmodifiableList(Arrays.asList(
(BrowserAppDelegate) new AddToHomeScreenPromotion(),
(BrowserAppDelegate) new ScreenshotDelegate(),
(BrowserAppDelegate) new BookmarkStateChangeDelegate(),
(BrowserAppDelegate) new ReaderViewBookmarkPromotion(),
(BrowserAppDelegate) new ContentNotificationsDelegate(),
(BrowserAppDelegate) new PostUpdateHandler(),
- new OfflineTabStatusDelegate()
- mTelemetryCorePingDelegate
+ new OfflineTabStatusDelegate(),
+ new TelemetryCorePingDelegate()
));
@NonNull
private SearchEngineManager mSearchEngineManager; // Contains reference to Context - DO NOT LEAK!
private boolean mHasResumed;
@Override
@@ -710,17 +709,17 @@ public class BrowserApp extends GeckoApp
final BrowserDB db = profile.getDB();
db.setSuggestedSites(suggestedSites);
JavaAddonManager.getInstance().init(appContext);
mSharedPreferencesHelper = new SharedPreferencesHelper(appContext);
mReadingListHelper = new ReadingListHelper(appContext, profile);
mAccountsHelper = new AccountsHelper(appContext, profile);
- initAdjustSDK(this, isInAutomation, mTelemetryCorePingDelegate);
+ initAdjustSDK(this, isInAutomation, addAttributionHelperListener());
if (AppConstants.MOZ_ANDROID_BEAM) {
NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this);
if (nfc != null) {
nfc.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageCallback() {
@Override
public NdefMessage createNdefMessage(NfcEvent event) {
Tab tab = Tabs.getInstance().getSelectedTab();
@@ -804,29 +803,38 @@ public class BrowserApp extends GeckoApp
final String serverUrl = TextUtils.isEmpty(serverExtra) ? SWITCHBOARD_SERVER : serverExtra;
new AsyncConfigLoader(context, serverUrl).execute();
}
private static void initTelemetryUploader(final boolean isInAutomation) {
TelemetryUploadService.setDisabled(isInAutomation);
}
- private static void initAdjustSDK(final Context context, final boolean isInAutomation, TelemetryCorePingDelegate delegate) {
+ private static void initAdjustSDK(final Context context, final boolean isInAutomation, final AttributionHelperListener listener) {
final AdjustHelperInterface adjustHelper = AdjustConstants.getAdjustHelper();
- adjustHelper.onCreate(context, AdjustConstants.MOZ_INSTALL_TRACKING_ADJUST_SDK_APP_TOKEN, delegate);
+ adjustHelper.onCreate(context, AdjustConstants.MOZ_INSTALL_TRACKING_ADJUST_SDK_APP_TOKEN, listener);
// Adjust stores enabled state so this is only necessary because users may have set
// their data preferences before this feature was implemented and we need to respect
// those before upload can occur in Adjust.onResume.
final SharedPreferences prefs = GeckoSharedPrefs.forApp(context);
final boolean enabled = !isInAutomation &&
prefs.getBoolean(GeckoPreferences.PREFS_HEALTHREPORT_UPLOAD_ENABLED, true);
adjustHelper.setEnabled(enabled);
}
+ private AttributionHelperListener addAttributionHelperListener() {
+ return new AttributionHelperListener() {
+ @Override
+ public void onCampaignIdChanged(String campaignId) {
+ CampaignIdMeasurements.updateCampaignIdPref(BrowserApp.this, campaignId);
+ }
+ };
+ }
+
private void showUpdaterPermissionSnackbar() {
SnackbarBuilder.SnackbarCallback allowCallback = new SnackbarBuilder.SnackbarCallback() {
@Override
public void onClick(View v) {
Permissions.from(BrowserApp.this)
.withPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.run();
}
--- a/mobile/android/base/java/org/mozilla/gecko/adjust/AttributionHelperListener.java
+++ b/mobile/android/base/java/org/mozilla/gecko/adjust/AttributionHelperListener.java
@@ -1,14 +1,16 @@
/* -*- 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.adjust;
/**
- * A callback Used along with the AdjustHelper for notifying when an Adjust Attribution
- * is available.
+ * We use this listener to notify when to store the campaign ID when we receive
+ * the attribution from the OnAttributionListener in the Adjust SDK. We can't directly access
+ * the attribution since we don't always compile against the Adjust SDK and use a stub
+ * in those cases.
*/
public interface AttributionHelperListener {
void onCampaignIdChanged(String campaignId);
}
--- a/mobile/android/base/java/org/mozilla/gecko/adjust/StubAdjustHelper.java
+++ b/mobile/android/base/java/org/mozilla/gecko/adjust/StubAdjustHelper.java
@@ -3,20 +3,17 @@
* 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.adjust;
import android.content.Context;
import android.content.Intent;
-import com.adjust.sdk.AdjustAttribution;
-import com.adjust.sdk.OnAttributionChangedListener;
-
-public class StubAdjustHelper implements AdjustHelperInterface, OnAttributionChangedListener {
+public class StubAdjustHelper implements AdjustHelperInterface {
public void onCreate(final Context context, final String appToken, final AttributionHelperListener listener) {
// Do nothing.
}
public void onPause() {
// Do nothing.
}
@@ -26,13 +23,9 @@ public class StubAdjustHelper implements
public void setEnabled(final boolean isEnabled) {
// Do nothing.
}
public void onReceive(final Context context, final Intent intent) {
// Do nothing.
}
-
- public void onAttributionChanged(AdjustAttribution attribution) {
- // Do nothing.
- }
}
--- a/mobile/android/base/java/org/mozilla/gecko/telemetry/TelemetryConstants.java
+++ b/mobile/android/base/java/org/mozilla/gecko/telemetry/TelemetryConstants.java
@@ -7,12 +7,9 @@ package org.mozilla.gecko.telemetry;
import org.mozilla.gecko.AppConstants;
public class TelemetryConstants {
// To test, set this to true & change "toolkit.telemetry.server" in about:config.
public static final boolean UPLOAD_ENABLED = AppConstants.MOZILLA_OFFICIAL; // Disabled for developer builds.
public static final String USER_AGENT =
"Firefox-Android-Telemetry/" + AppConstants.MOZ_APP_VERSION + " (" + AppConstants.MOZ_APP_UA_NAME + ")";
-
- public static final String PREF_SERVER_URL = "telemetry-serverUrl";
- public static final String PREF_CAMPAIGN_ID = "campaignId";
}
--- a/mobile/android/base/java/org/mozilla/gecko/telemetry/TelemetryCorePingDelegate.java
+++ b/mobile/android/base/java/org/mozilla/gecko/telemetry/TelemetryCorePingDelegate.java
@@ -9,16 +9,17 @@ package org.mozilla.gecko.telemetry;
import android.content.SharedPreferences;
import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
import android.util.Log;
import org.mozilla.gecko.BrowserApp;
import org.mozilla.gecko.GeckoProfile;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.adjust.AttributionHelperListener;
+import org.mozilla.gecko.telemetry.measurements.CampaignIdMeasurements;
import org.mozilla.gecko.delegates.BrowserAppDelegateWithReference;
import org.mozilla.gecko.distribution.DistributionStoreCallback;
import org.mozilla.gecko.search.SearchEngineManager;
import org.mozilla.gecko.sync.ExtendedJSONObject;
import org.mozilla.gecko.telemetry.measurements.SearchCountMeasurements;
import org.mozilla.gecko.telemetry.measurements.SessionMeasurements;
import org.mozilla.gecko.telemetry.pingbuilders.TelemetryCorePingBuilder;
import org.mozilla.gecko.util.StringUtils;
@@ -148,37 +149,39 @@ public class TelemetryCorePingDelegate e
final SessionMeasurements.SessionMeasurementsContainer sessionMeasurementsContainer =
sessionMeasurements.getAndResetSessionMeasurements(activity);
final TelemetryCorePingBuilder pingBuilder = new TelemetryCorePingBuilder(activity)
.setClientID(clientID)
.setDefaultSearchEngine(TelemetryCorePingBuilder.getEngineIdentifier(engine))
.setProfileCreationDate(TelemetryCorePingBuilder.getProfileCreationDate(activity, profile))
.setSequenceNumber(TelemetryCorePingBuilder.getAndIncrementSequenceNumber(sharedPrefs))
.setSessionCount(sessionMeasurementsContainer.sessionCount)
- .setSessionDuration(sessionMeasurementsContainer.elapsedSeconds)
- .setOptCampaignId(activity);
- maybeSetOptionalMeasurements(sharedPrefs, pingBuilder);
+ .setSessionDuration(sessionMeasurementsContainer.elapsedSeconds);
+ maybeSetOptionalMeasurements(sharedPrefs, pingBuilder, activity);
getTelemetryDispatcher(activity).queuePingForUpload(activity, pingBuilder);
}
});
}
- private void maybeSetOptionalMeasurements(final SharedPreferences sharedPrefs, final TelemetryCorePingBuilder pingBuilder) {
+ private void maybeSetOptionalMeasurements(final SharedPreferences sharedPrefs, final TelemetryCorePingBuilder pingBuilder,
+ final BrowserApp activity) {
final String distributionId = sharedPrefs.getString(DistributionStoreCallback.PREF_DISTRIBUTION_ID, null);
if (distributionId != null) {
pingBuilder.setOptDistributionID(distributionId);
}
final ExtendedJSONObject searchCounts = SearchCountMeasurements.getAndZeroSearch(sharedPrefs);
if (searchCounts.size() > 0) {
pingBuilder.setOptSearchCounts(searchCounts);
}
+
+ final String campaignId = CampaignIdMeasurements.getCampaignIdFromPrefs(activity);
+ if (campaignId != null) {
+ pingBuilder.setOptCampaignId(campaignId);
+ }
}
@Override
public void onCampaignIdChanged(String campaignId) {
- GeckoSharedPrefs.forProfile(getBrowserApp())
- .edit()
- .putString(TelemetryConstants.PREF_CAMPAIGN_ID, campaignId)
- .apply();
+ CampaignIdMeasurements.updateCampaignIdPref(getBrowserApp(), campaignId);
}
}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/telemetry/measurements/CampaignIdMeasurements.java
@@ -0,0 +1,37 @@
+/*
+ * 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.telemetry.measurements;
+
+import android.support.annotation.NonNull;
+import android.text.TextUtils;
+
+import org.mozilla.gecko.BrowserApp;
+import org.mozilla.gecko.GeckoSharedPrefs;
+import org.mozilla.gecko.adjust.AttributionHelperListener;
+
+/**
+ * A class to retrieve and store the campaign Id pref that is used when the Adjust SDK gives us
+ * new attribution from the {@link AttributionHelperListener}.
+ */
+public class CampaignIdMeasurements {
+ private static final String PREF_CAMPAIGN_ID = "campaignId";
+
+ public static String getCampaignIdFromPrefs(@NonNull final BrowserApp activity) {
+ return GeckoSharedPrefs.forProfile(activity)
+ .getString(PREF_CAMPAIGN_ID, null);
+ }
+
+ public static void updateCampaignIdPref(@NonNull final BrowserApp activity, @NonNull final String campaignId) {
+ if (TextUtils.isEmpty(campaignId)) {
+ return;
+ }
+ GeckoSharedPrefs.forProfile(activity)
+ .edit()
+ .putString(PREF_CAMPAIGN_ID, campaignId)
+ .apply();
+ }
+}
--- a/mobile/android/base/java/org/mozilla/gecko/telemetry/pingbuilders/TelemetryCorePingBuilder.java
+++ b/mobile/android/base/java/org/mozilla/gecko/telemetry/pingbuilders/TelemetryCorePingBuilder.java
@@ -39,23 +39,23 @@ import java.util.concurrent.TimeUnit;
* See https://gecko.readthedocs.org/en/latest/toolkit/components/telemetry/telemetry/core-ping.html
* for details on the core ping.
*/
public class TelemetryCorePingBuilder extends TelemetryPingBuilder {
private static final String LOGTAG = StringUtils.safeSubstring(TelemetryCorePingBuilder.class.getSimpleName(), 0, 23);
// For legacy reasons, this preference key is not namespaced with "core".
private static final String PREF_SEQ_COUNT = "telemetry-seqCount";
+ private static final String PREF_CAMPAIGN_ID = "campaignId";
private static final String NAME = "core";
private static final int VERSION_VALUE = 7; // For version history, see toolkit/components/telemetry/docs/core-ping.rst
private static final String OS_VALUE = "Android";
private static final String ARCHITECTURE = "arch";
- private static final String CAMPAIGN_ID = "campaignId";
private static final String CLIENT_ID = "clientId";
private static final String DEFAULT_SEARCH_ENGINE = "defaultSearch";
private static final String DEVICE = "device";
private static final String DISTRIBUTION_ID = "distributionId";
private static final String EXPERIMENTS = "experiments";
private static final String LOCALE = "locale";
private static final String OS_ATTR = "os";
private static final String OS_VERSION = "osversion";
@@ -153,24 +153,21 @@ public class TelemetryCorePingBuilder ex
} else if (searchCounts.size() == 0) {
throw new IllegalStateException("Expected non-empty search counts");
}
payload.put(SEARCH_COUNTS, searchCounts);
return this;
}
- public TelemetryCorePingBuilder setOptCampaignId(final Context context) {
- final String campaignId = GeckoSharedPrefs.forProfile(context)
- .getString(TelemetryConstants.PREF_CAMPAIGN_ID, null);
- Log.d(LOGTAG, "Got adjust campaignId from prefs: " + campaignId);
+ public TelemetryCorePingBuilder setOptCampaignId(final String campaignId) {
if (campaignId == null) {
- throw new IllegalStateException("Received empty string.");
+ throw new IllegalStateException("Expected non-null campaign ID.");
}
- payload.put(TelemetryConstants.PREF_CAMPAIGN_ID, campaignId);
+ payload.put(PREF_CAMPAIGN_ID, campaignId);
return this;
}
/**
* @param date The profile creation date in days to the unix epoch (not millis!), or null if there is an error.
*/
public TelemetryCorePingBuilder setProfileCreationDate(@Nullable final Long date) {
if (date != null && date < 0) {
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -588,16 +588,17 @@ gbjar.sources += ['java/org/mozilla/geck
'tabs/TabPanelBackButton.java',
'tabs/TabsGridLayout.java',
'tabs/TabsLayoutAdapter.java',
'tabs/TabsLayoutItemView.java',
'tabs/TabsListLayout.java',
'tabs/TabsPanel.java',
'tabs/TabsPanelThumbnailView.java',
'Telemetry.java',
+ 'telemetry/measurements/CampaignIdMeasurements.java',
'telemetry/measurements/SearchCountMeasurements.java',
'telemetry/measurements/SessionMeasurements.java',
'telemetry/pingbuilders/TelemetryCorePingBuilder.java',
'telemetry/pingbuilders/TelemetryPingBuilder.java',
'telemetry/schedulers/TelemetryUploadAllPingsImmediatelyScheduler.java',
'telemetry/schedulers/TelemetryUploadScheduler.java',
'telemetry/stores/TelemetryJSONFilePingStore.java',
'telemetry/stores/TelemetryPingStore.java',