mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 1273689 - Move core ping upload to BrowserAppDelegate. r=sebastian
This lets us put the two paths of upload code all in the same place. MozReview-Commit-ID: BUsdyEAcdDO --HG-- extra : rebase_source : a854facb606afd95764feac19fb5ef64f216addf
This commit is contained in:
parent
5e633581d1
commit
8bae604593
@ -9,8 +9,6 @@ import android.Manifest;
|
||||
import android.app.DownloadManager;
|
||||
import android.os.Environment;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.WorkerThread;
|
||||
import org.json.JSONArray;
|
||||
import org.mozilla.gecko.adjust.AdjustHelperInterface;
|
||||
import org.mozilla.gecko.annotation.RobocopTarget;
|
||||
@ -79,9 +77,8 @@ import org.mozilla.gecko.tabs.TabHistoryFragment;
|
||||
import org.mozilla.gecko.tabs.TabHistoryPage;
|
||||
import org.mozilla.gecko.tabs.TabsPanel;
|
||||
import org.mozilla.gecko.telemetry.TelemetryUploadService;
|
||||
import org.mozilla.gecko.telemetry.TelemetryCorePingUploadDelegate;
|
||||
import org.mozilla.gecko.telemetry.measurements.SearchCountMeasurements;
|
||||
import org.mozilla.gecko.telemetry.TelemetryDispatcher;
|
||||
import org.mozilla.gecko.telemetry.UploadTelemetryCorePingCallback;
|
||||
import org.mozilla.gecko.telemetry.measurements.SessionMeasurements;
|
||||
import org.mozilla.gecko.toolbar.AutocompleteHandler;
|
||||
import org.mozilla.gecko.toolbar.BrowserToolbar;
|
||||
@ -312,13 +309,13 @@ public class BrowserApp extends GeckoApp
|
||||
(BrowserAppDelegate) new ScreenshotDelegate(),
|
||||
(BrowserAppDelegate) new BookmarkStateChangeDelegate(),
|
||||
(BrowserAppDelegate) new ReaderViewBookmarkPromotion(),
|
||||
(BrowserAppDelegate) new ContentNotificationsDelegate()
|
||||
(BrowserAppDelegate) new ContentNotificationsDelegate(),
|
||||
new TelemetryCorePingUploadDelegate()
|
||||
));
|
||||
|
||||
@NonNull
|
||||
private SearchEngineManager mSearchEngineManager; // Contains reference to Context - DO NOT LEAK!
|
||||
|
||||
private TelemetryDispatcher mTelemetryDispatcher; // lazy.
|
||||
private final SessionMeasurements mSessionMeasurements = new SessionMeasurements();
|
||||
|
||||
private boolean mHasResumed;
|
||||
@ -1086,15 +1083,6 @@ public class BrowserApp extends GeckoApp
|
||||
}
|
||||
});
|
||||
|
||||
// We don't upload in onCreate because that's only called when the Activity needs to be instantiated
|
||||
// and it's possible the system will never free the Activity from memory.
|
||||
//
|
||||
// We don't upload in onResume/onPause because that will be called each time the Activity is obscured,
|
||||
// including by our own Activities/dialogs, and there is no reason to upload each time we're unobscured.
|
||||
//
|
||||
// So we're left with onStart/onStop.
|
||||
mSearchEngineManager.getEngine(new UploadTelemetryCorePingCallback(BrowserApp.this));
|
||||
|
||||
for (final BrowserAppDelegate delegate : delegates) {
|
||||
delegate.onStart(this);
|
||||
}
|
||||
@ -3923,12 +3911,8 @@ public class BrowserApp extends GeckoApp
|
||||
@Override
|
||||
public int getLayout() { return R.layout.gecko_app; }
|
||||
|
||||
@WorkerThread // via constructor
|
||||
public TelemetryDispatcher getTelemetryDispatcher() {
|
||||
if (mTelemetryDispatcher == null) {
|
||||
mTelemetryDispatcher = new TelemetryDispatcher(getProfile().getDir().getAbsolutePath());
|
||||
}
|
||||
return mTelemetryDispatcher;
|
||||
public SearchEngineManager getSearchEngineManager() {
|
||||
return mSearchEngineManager;
|
||||
}
|
||||
|
||||
public SessionMeasurements getSessionMeasurementDelegate() {
|
||||
|
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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.delegates.BrowserAppDelegate;
|
||||
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;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* An activity-lifecycle delegate for uploading the core ping.
|
||||
*/
|
||||
public class TelemetryCorePingUploadDelegate extends BrowserAppDelegate {
|
||||
private static final String LOGTAG = StringUtils.safeSubstring(
|
||||
"Gecko" + TelemetryCorePingUploadDelegate.class.getSimpleName(), 0, 23);
|
||||
|
||||
private TelemetryDispatcher telemetryDispatcher; // lazy
|
||||
|
||||
@Override
|
||||
public void onStart(final BrowserApp browserApp) {
|
||||
// We don't upload in onCreate because that's only called when the Activity needs to be instantiated
|
||||
// and it's possible the system will never free the Activity from memory.
|
||||
//
|
||||
// We don't upload in onResume/onPause because that will be called each time the Activity is obscured,
|
||||
// including by our own Activities/dialogs, and there is no reason to upload each time we're unobscured.
|
||||
//
|
||||
// So we're left with onStart/onStop.
|
||||
final SearchEngineManager searchEngineManager = browserApp.getSearchEngineManager();
|
||||
searchEngineManager.getEngine(new UploadTelemetryCorePingCallback(browserApp));
|
||||
}
|
||||
|
||||
@WorkerThread // via constructor
|
||||
private TelemetryDispatcher getTelemetryDispatcher(final BrowserApp browserApp) {
|
||||
if (telemetryDispatcher == null) {
|
||||
final String profilePath = browserApp.getProfile().getDir().getAbsolutePath();
|
||||
telemetryDispatcher = new TelemetryDispatcher(profilePath);
|
||||
}
|
||||
return telemetryDispatcher;
|
||||
}
|
||||
|
||||
private class UploadTelemetryCorePingCallback implements SearchEngineManager.SearchEngineCallback {
|
||||
private final WeakReference<BrowserApp> activityWeakReference;
|
||||
|
||||
private UploadTelemetryCorePingCallback(final BrowserApp activity) {
|
||||
this.activityWeakReference = new WeakReference<>(activity);
|
||||
}
|
||||
|
||||
// May be called from any thread.
|
||||
@Override
|
||||
public void execute(@Nullable final org.mozilla.gecko.search.SearchEngine engine) {
|
||||
// Don't waste resources queueing to the background thread if we don't have a reference.
|
||||
if (this.activityWeakReference.get() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The containing method can be called from onStart: queue this work so that
|
||||
// the first launch of the activity doesn't trigger profile init too early.
|
||||
//
|
||||
// Additionally, getAndIncrementSequenceNumber must be called from a worker thread.
|
||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||
@WorkerThread
|
||||
@Override
|
||||
public void run() {
|
||||
final BrowserApp activity = activityWeakReference.get();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final GeckoProfile profile = activity.getProfile();
|
||||
if (!TelemetryUploadService.isUploadEnabledByProfileConfig(activity, profile)) {
|
||||
Log.d(LOGTAG, "Core ping upload disabled by profile config. Returning.");
|
||||
return;
|
||||
}
|
||||
|
||||
final String clientID;
|
||||
try {
|
||||
clientID = profile.getClientId();
|
||||
} catch (final IOException e) {
|
||||
Log.w(LOGTAG, "Unable to get client ID to generate core ping: " + e);
|
||||
return;
|
||||
}
|
||||
|
||||
// Each profile can have different telemetry data so we intentionally grab the shared prefs for the profile.
|
||||
final SharedPreferences sharedPrefs = GeckoSharedPrefs.forProfileName(activity, profile.getName());
|
||||
final SessionMeasurements.SessionMeasurementsContainer sessionMeasurementsContainer =
|
||||
activity.getSessionMeasurementDelegate().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);
|
||||
maybeSetOptionalMeasurements(sharedPrefs, pingBuilder);
|
||||
|
||||
getTelemetryDispatcher(activity).queuePingForUpload(activity, pingBuilder);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void maybeSetOptionalMeasurements(final SharedPreferences sharedPrefs, final TelemetryCorePingBuilder pingBuilder) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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.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.SessionMeasurementsContainer;
|
||||
import org.mozilla.gecko.telemetry.pingbuilders.TelemetryCorePingBuilder;
|
||||
import org.mozilla.gecko.util.StringUtils;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* A search engine callback that will attempt to upload the core ping.
|
||||
*/
|
||||
public class UploadTelemetryCorePingCallback implements SearchEngineManager.SearchEngineCallback {
|
||||
private static final String LOGTAG = StringUtils.safeSubstring(
|
||||
"Gecko" + UploadTelemetryCorePingCallback.class.getSimpleName(), 0, 23);
|
||||
|
||||
private final WeakReference<BrowserApp> activityWeakReference;
|
||||
|
||||
public UploadTelemetryCorePingCallback(final BrowserApp activity) {
|
||||
this.activityWeakReference = new WeakReference<>(activity);
|
||||
}
|
||||
|
||||
// May be called from any thread.
|
||||
@Override
|
||||
public void execute(@Nullable final org.mozilla.gecko.search.SearchEngine engine) {
|
||||
// Don't waste resources queueing to the background thread if we don't have a reference.
|
||||
if (this.activityWeakReference.get() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The containing method can be called from onStart: queue this work so that
|
||||
// the first launch of the activity doesn't trigger profile init too early.
|
||||
//
|
||||
// Additionally, getAndIncrementSequenceNumber must be called from a worker thread.
|
||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||
@WorkerThread
|
||||
@Override
|
||||
public void run() {
|
||||
final BrowserApp activity = activityWeakReference.get();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final GeckoProfile profile = activity.getProfile();
|
||||
if (!TelemetryUploadService.isUploadEnabledByProfileConfig(activity, profile)) {
|
||||
Log.d(LOGTAG, "Core ping upload disabled by profile config. Returning.");
|
||||
return;
|
||||
}
|
||||
|
||||
final String clientID;
|
||||
try {
|
||||
clientID = profile.getClientId();
|
||||
} catch (final IOException e) {
|
||||
Log.w(LOGTAG, "Unable to get client ID to generate core ping: " + e);
|
||||
return;
|
||||
}
|
||||
|
||||
// Each profile can have different telemetry data so we intentionally grab the shared prefs for the profile.
|
||||
final SharedPreferences sharedPrefs = GeckoSharedPrefs.forProfileName(activity, profile.getName());
|
||||
final SessionMeasurementsContainer sessionMeasurementsContainer =
|
||||
activity.getSessionMeasurementDelegate().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);
|
||||
maybeSetOptionalMeasurements(sharedPrefs, pingBuilder);
|
||||
|
||||
activity.getTelemetryDispatcher().queuePingForUpload(activity, pingBuilder);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void maybeSetOptionalMeasurements(final SharedPreferences sharedPrefs, final TelemetryCorePingBuilder pingBuilder) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -589,10 +589,10 @@ gbjar.sources += ['java/org/mozilla/gecko/' + x for x in [
|
||||
'telemetry/stores/TelemetryJSONFilePingStore.java',
|
||||
'telemetry/stores/TelemetryPingStore.java',
|
||||
'telemetry/TelemetryConstants.java',
|
||||
'telemetry/TelemetryCorePingUploadDelegate.java',
|
||||
'telemetry/TelemetryDispatcher.java',
|
||||
'telemetry/TelemetryPing.java',
|
||||
'telemetry/TelemetryUploadService.java',
|
||||
'telemetry/UploadTelemetryCorePingCallback.java',
|
||||
'TelemetryContract.java',
|
||||
'text/FloatingActionModeCallback.java',
|
||||
'text/FloatingToolbarTextSelection.java',
|
||||
|
Loading…
Reference in New Issue
Block a user