Bug 1274433 - Construct TelemetryDispatcher on background thread. r=ahunt draft
authorMichael Comella <michael.l.comella@gmail.com>
Fri, 20 May 2016 18:00:22 -0700
changeset 369264 108d30fed9802bf7e2bfb3d35aca1126c808e1b6
parent 369154 00ed91d9c2c83fec8c61565ef1f73ed7a7df724a
child 521533 08384d0d998d61246ada38d205fff7d0b6b30cc0
push id18817
push usermichael.l.comella@gmail.com
push dateSat, 21 May 2016 01:00:16 +0000
reviewersahunt
bugs1274433
milestone49.0a1
Bug 1274433 - Construct TelemetryDispatcher on background thread. r=ahunt MozReview-Commit-ID: 6H5Wp4uzNQb
mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
mobile/android/base/java/org/mozilla/gecko/telemetry/TelemetryDispatcher.java
mobile/android/base/java/org/mozilla/gecko/telemetry/stores/TelemetryJSONFilePingStore.java
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -314,17 +314,17 @@ public class BrowserApp extends GeckoApp
             (BrowserAppDelegate) new BookmarkStateChangeDelegate(),
             (BrowserAppDelegate) new ReaderViewBookmarkPromotion(),
             (BrowserAppDelegate) new ContentNotificationsDelegate()
     ));
 
     @NonNull
     private SearchEngineManager mSearchEngineManager; // Contains reference to Context - DO NOT LEAK!
 
-    private TelemetryDispatcher mTelemetryDispatcher;
+    private TelemetryDispatcher mTelemetryDispatcher; // lazy.
     private final SessionMeasurements mSessionMeasurements = new SessionMeasurements();
 
     private boolean mHasResumed;
 
     @Override
     public View onCreateView(final String name, final Context context, final AttributeSet attrs) {
         final View view;
         if (BrowserToolbar.class.getName().equals(name)) {
@@ -698,17 +698,16 @@ public class BrowserApp extends GeckoApp
         final GeckoProfile profile = getProfile();
 
         // We want to upload the telemetry core ping as soon after startup as possible. It relies on the
         // Distribution being initialized. If you move this initialization, ensure it plays well with telemetry.
         final Distribution distribution = Distribution.init(this);
         distribution.addOnDistributionReadyCallback(new DistributionStoreCallback(this, profile.getName()));
 
         mSearchEngineManager = new SearchEngineManager(this, distribution);
-        mTelemetryDispatcher = new TelemetryDispatcher(profile.getDir().getAbsolutePath());
 
         // Init suggested sites engine in BrowserDB.
         final SuggestedSites suggestedSites = new SuggestedSites(appContext, distribution);
         final BrowserDB db = profile.getDB();
         db.setSuggestedSites(suggestedSites);
 
         JavaAddonManager.getInstance().init(appContext);
         mSharedPreferencesHelper = new SharedPreferencesHelper(appContext);
@@ -3915,17 +3914,21 @@ public class BrowserApp extends GeckoApp
     @Override
     public void onEditSuggestion(String suggestion) {
         mBrowserToolbar.onEditSuggestion(suggestion);
     }
 
     @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 SessionMeasurements getSessionMeasurementDelegate() {
         return mSessionMeasurements;
     }
 
     // For use from tests only.
--- a/mobile/android/base/java/org/mozilla/gecko/telemetry/TelemetryDispatcher.java
+++ b/mobile/android/base/java/org/mozilla/gecko/telemetry/TelemetryDispatcher.java
@@ -2,16 +2,17 @@
  * 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.Context;
+import android.support.annotation.WorkerThread;
 import android.util.Log;
 import org.mozilla.gecko.telemetry.pingbuilders.TelemetryCorePingBuilder;
 import org.mozilla.gecko.telemetry.schedulers.TelemetryUploadScheduler;
 import org.mozilla.gecko.telemetry.schedulers.TelemetryUploadAllPingsImmediatelyScheduler;
 import org.mozilla.gecko.telemetry.stores.TelemetryJSONFilePingStore;
 import org.mozilla.gecko.telemetry.stores.TelemetryPingStore;
 import org.mozilla.gecko.util.ThreadUtils;
 
@@ -51,16 +52,17 @@ public class TelemetryDispatcher {
 
     private static final String STORE_CONTAINER_DIR_NAME = "telemetry_java";
     private static final String CORE_STORE_DIR_NAME = "core";
 
     private final TelemetryJSONFilePingStore coreStore;
 
     private final TelemetryUploadAllPingsImmediatelyScheduler uploadAllPingsImmediatelyScheduler;
 
+    @WorkerThread // via TelemetryJSONFilePingStore
     public TelemetryDispatcher(final String profilePath) {
         final String storePath = profilePath + File.separator + STORE_CONTAINER_DIR_NAME;
 
         // There are measurements in the core ping (e.g. seq #) that would ideally be atomically updated
         // when the ping is stored. However, for simplicity, we use the json store and accept the possible
         // loss of data (see bug 1243585 comment 16+ for more).
         coreStore = new TelemetryJSONFilePingStore(new File(storePath, CORE_STORE_DIR_NAME));
 
--- a/mobile/android/base/java/org/mozilla/gecko/telemetry/stores/TelemetryJSONFilePingStore.java
+++ b/mobile/android/base/java/org/mozilla/gecko/telemetry/stores/TelemetryJSONFilePingStore.java
@@ -4,16 +4,17 @@
  * file, you can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
 package org.mozilla.gecko.telemetry.stores;
 
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.support.annotation.VisibleForTesting;
+import android.support.annotation.WorkerThread;
 import android.util.Log;
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.mozilla.gecko.sync.ExtendedJSONObject;
 import org.mozilla.gecko.sync.NonObjectJSONException;
 import org.mozilla.gecko.telemetry.TelemetryPing;
 import org.mozilla.gecko.util.FileUtils;
 import org.mozilla.gecko.util.FileUtils.FileLastModifiedComparator;
@@ -69,16 +70,17 @@ public class TelemetryJSONFilePingStore 
     // We keep the key names short to reduce storage size impact.
     @VisibleForTesting static final String KEY_PAYLOAD = "p";
     @VisibleForTesting static final String KEY_URL_PATH = "u";
 
     private final File storeDir;
     private final FilenameFilter uuidFilenameFilter;
     private final FileLastModifiedComparator fileLastModifiedComparator = new FileLastModifiedComparator();
 
+    @WorkerThread // Writes to disk
     public TelemetryJSONFilePingStore(final File storeDir) {
         this.storeDir = storeDir;
         this.storeDir.mkdirs();
         uuidFilenameFilter = new FilenameRegexFilter(UUIDUtil.UUID_PATTERN);
     }
 
     @VisibleForTesting File getPingFile(final String docID) {
         return new File(storeDir, docID);