[go: up one dir, main page]

[BackgroundSync] Move read and write of shared preferences to an AsyncTask

Merge into M45

TBR=jdduke@chromium.org
BUG=520105

Review URL: https://codereview.chromium.org/1288593003

Cr-Commit-Position: refs/heads/master@{#345118}
(cherry picked from commit 3fd1c36bf4c6cf03586c74bf95d051787d7c86b2)

Review URL: https://codereview.chromium.org/1315863003 .

Cr-Commit-Position: refs/branch-heads/2454@{#429}
Cr-Branched-From: 12bfc3360892ec53cd00fc239a47e5298beb063b-refs/heads/master@{#338390}
diff --git a/content/browser/android/background_sync_launcher_android.cc b/content/browser/android/background_sync_launcher_android.cc
index 78110c1..693817ba 100644
--- a/content/browser/android/background_sync_launcher_android.cc
+++ b/content/browser/android/background_sync_launcher_android.cc
@@ -46,7 +46,8 @@
   if (was_launching != now_launching) {
     JNIEnv* env = base::android::AttachCurrentThread();
     Java_BackgroundSyncLauncher_setLaunchWhenNextOnline(
-        env, java_launcher_.obj(), now_launching);
+        env, java_launcher_.obj(), base::android::GetApplicationContext(),
+        now_launching);
   }
 }
 
diff --git a/content/public/android/java/src/org/chromium/content/browser/BackgroundSyncLauncher.java b/content/public/android/java/src/org/chromium/content/browser/BackgroundSyncLauncher.java
index 9da674d..c9c8fbed 100644
--- a/content/public/android/java/src/org/chromium/content/browser/BackgroundSyncLauncher.java
+++ b/content/public/android/java/src/org/chromium/content/browser/BackgroundSyncLauncher.java
@@ -6,6 +6,7 @@
 
 import android.content.Context;
 import android.content.SharedPreferences;
+import android.os.AsyncTask;
 import android.preference.PreferenceManager;
 
 import org.chromium.base.CalledByNative;
@@ -27,8 +28,6 @@
     // BackgroundSyncLauncherAndroid, if any. If it is non-null then the browser is running.
     private static BackgroundSyncLauncher sInstance;
 
-    private final SharedPreferences mSharedPreferences;
-
     /**
      * Create a BackgroundSyncLauncher object, which is owned by C++.
      * @param context The app context.
@@ -55,26 +54,53 @@
     }
 
     /**
-     * Set interest (or disinterest) in launching the browser the next time the device goes online
-     * after the browser closes. On creation of the {@link BackgroundSyncLauncher} class (on browser
-     * start) this value is reset to false.
+     * Callback for {@link #shouldLaunchWhenNextOnline}. The run method is invoked on the UI thread.
      */
-    @VisibleForTesting
-    @CalledByNative
-    protected void setLaunchWhenNextOnline(boolean shouldLaunch) {
-        mSharedPreferences.edit()
-                .putBoolean(PREF_BACKGROUND_SYNC_LAUNCH_NEXT_ONLINE, shouldLaunch)
-                .apply();
-    }
+    public static interface ShouldLaunchCallback { public void run(Boolean shouldLaunch); }
 
     /**
      * Returns whether the browser should be launched when the device next goes online.
      * This is set by C++ and reset to false each time {@link BackgroundSyncLauncher}'s singleton is
-     * created (the native browser is started).
+     * created (the native browser is started). This call is asynchronous and will run the callback
+     * on the UI thread when complete.
+     * @param context The application context.
      * @param sharedPreferences The shared preferences.
      */
-    protected static boolean shouldLaunchWhenNextOnline(SharedPreferences sharedPreferences) {
-        return sharedPreferences.getBoolean(PREF_BACKGROUND_SYNC_LAUNCH_NEXT_ONLINE, false);
+    protected static void shouldLaunchWhenNextOnline(
+            final Context context, final ShouldLaunchCallback callback) {
+        new AsyncTask<Void, Void, Boolean>() {
+            @Override
+            protected Boolean doInBackground(Void... params) {
+                SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+                return prefs.getBoolean(PREF_BACKGROUND_SYNC_LAUNCH_NEXT_ONLINE, false);
+            }
+            @Override
+            protected void onPostExecute(Boolean shouldLaunch) {
+                callback.run(shouldLaunch);
+            }
+        }.execute();
+    }
+
+    /**
+     * Set interest (or disinterest) in launching the browser the next time the device goes online
+     * after the browser closes. On creation of the {@link BackgroundSyncLauncher} class (on browser
+     * start) this value is reset to false. This is set by C++ and reset to false each time
+     * {@link BackgroundSyncLauncher}'s singleton is created (the native browser is started). This
+     * call is asynchronous.
+     */
+    @VisibleForTesting
+    @CalledByNative
+    protected void setLaunchWhenNextOnline(final Context context, final boolean shouldLaunch) {
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... params) {
+                SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+                prefs.edit()
+                        .putBoolean(PREF_BACKGROUND_SYNC_LAUNCH_NEXT_ONLINE, shouldLaunch)
+                        .apply();
+                return null;
+            }
+        }.execute();
     }
 
     /**
@@ -86,7 +112,6 @@
     }
 
     private BackgroundSyncLauncher(Context context) {
-        mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
-        setLaunchWhenNextOnline(false);
+        setLaunchWhenNextOnline(context, false);
     }
 }
\ No newline at end of file
diff --git a/content/public/android/java/src/org/chromium/content/browser/BackgroundSyncLauncherService.java b/content/public/android/java/src/org/chromium/content/browser/BackgroundSyncLauncherService.java
index 22190ab..fd92e55 100644
--- a/content/public/android/java/src/org/chromium/content/browser/BackgroundSyncLauncherService.java
+++ b/content/public/android/java/src/org/chromium/content/browser/BackgroundSyncLauncherService.java
@@ -9,7 +9,6 @@
 import android.content.Intent;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
-import android.preference.PreferenceManager;
 import android.support.v4.content.WakefulBroadcastReceiver;
 
 import org.chromium.base.Log;
@@ -28,8 +27,9 @@
     private static final String TAG = "cr.BgSyncLauncher";
 
     /**
-     * Receiver for network connection change broadcasts. If the device is online and the browser
-     * should be launched, it starts the BackgroundSyncLauncherService.
+     * Receiver for network connection change broadcasts. If the device is online
+     * and the browser isn't running it starts the BackgroundSyncLauncherService.
+     * The service will then launch the browser if necessary.
      *
      * This class is public so that it can be instantiated by the Android runtime.
      */
@@ -39,9 +39,7 @@
             // If online, the browser isn't running, and the browser has requested
             // it be launched the next time the device is online, start the browser.
             if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())
-                    && isOnline(context) && !BackgroundSyncLauncher.hasInstance()
-                    && BackgroundSyncLauncher.shouldLaunchWhenNextOnline(
-                               PreferenceManager.getDefaultSharedPreferences(context))) {
+                    && isOnline(context) && !BackgroundSyncLauncher.hasInstance()) {
                 startService(context);
             }
         }
@@ -79,14 +77,24 @@
         }
     }
 
-    private void onOnline(Context context) {
+    private void onOnline(final Context context) {
         ThreadUtils.assertOnUiThread();
 
-        // Start the browser. The browser's BackgroundSyncManager (for the active profile) will
-        // start, check the network, and run any necessary sync events. It runs without a wake lock.
-        // TODO(jkarlin): Protect the browser sync event with a wake lock. See crbug.com/486020.
-        Log.v(TAG, "Starting Browser after coming online");
-        launchBrowser(context);
+        BackgroundSyncLauncher.ShouldLaunchCallback callback =
+                new BackgroundSyncLauncher.ShouldLaunchCallback() {
+                    @Override
+                    public void run(Boolean shouldLaunch) {
+                        if (!shouldLaunch) return;
+                        // Start the browser. The browser's BackgroundSyncManager (for the active
+                        // profile) will start, check the network, and run any necessary sync
+                        // events. It runs without a wake lock.
+                        // TODO(jkarlin): Protect the browser sync event with a wake lock. See
+                        // crbug.com/486020.
+                        Log.v(TAG, "Starting Browser after coming online");
+                        launchBrowser(context);
+                    }
+                };
+        BackgroundSyncLauncher.shouldLaunchWhenNextOnline(context, callback);
     }
 
     @SuppressFBWarnings("DM_EXIT")
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/BackgroundSyncLauncherTest.java b/content/public/android/javatests/src/org/chromium/content/browser/BackgroundSyncLauncherTest.java
index c058953..0fc40e3 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/BackgroundSyncLauncherTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/BackgroundSyncLauncherTest.java
@@ -6,7 +6,6 @@
 
 import android.content.Context;
 import android.content.Intent;
-import android.content.SharedPreferences;
 import android.net.ConnectivityManager;
 import android.test.InstrumentationTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -14,6 +13,8 @@
 import org.chromium.base.test.util.AdvancedMockContext;
 import org.chromium.base.test.util.Feature;
 
+import java.util.concurrent.Semaphore;
+
 /**
  * Tests {@link BackgroundSyncLauncherService} and {@link BackgroundSyncLauncherService.Receiver}.
  */
@@ -21,8 +22,7 @@
     private Context mContext;
     private BackgroundSyncLauncher mLauncher;
     private MockReceiver mLauncherServiceReceiver;
-
-    private SharedPreferences mPrefs;
+    private Boolean mShouldLaunchResult;
 
     static class MockReceiver extends BackgroundSyncLauncherService.Receiver {
         private boolean mIsOnline = true;
@@ -56,9 +56,6 @@
         mContext = new AdvancedMockContext(getInstrumentation().getTargetContext());
         mLauncher = BackgroundSyncLauncher.create(mContext);
         mLauncherServiceReceiver = new MockReceiver();
-
-        mPrefs = mContext.getSharedPreferences(
-                mContext.getPackageName() + "_preferences", Context.MODE_PRIVATE);
     }
 
     private void deleteLauncherInstance() {
@@ -72,6 +69,31 @@
         mLauncherServiceReceiver.checkExpectations(shouldStart);
     }
 
+    private Boolean shouldLaunchWhenNextOnlineSync() {
+        mShouldLaunchResult = false;
+
+        // Use a semaphore to wait for the callback to be called.
+        final Semaphore semaphore = new Semaphore(0);
+
+        BackgroundSyncLauncher.ShouldLaunchCallback callback =
+                new BackgroundSyncLauncher.ShouldLaunchCallback() {
+                    @Override
+                    public void run(Boolean shouldLaunch) {
+                        mShouldLaunchResult = shouldLaunch;
+                        semaphore.release();
+                    }
+                };
+
+        BackgroundSyncLauncher.shouldLaunchWhenNextOnline(mContext, callback);
+        try {
+            // Wait on the callback to be called.
+            semaphore.acquire();
+        } catch (InterruptedException e) {
+            fail("Failed to acquire semaphore");
+        }
+        return mShouldLaunchResult;
+    }
+
     @SmallTest
     @Feature({"BackgroundSync"})
     public void testHasInstance() {
@@ -83,55 +105,35 @@
     @SmallTest
     @Feature({"BackgroundSync"})
     public void testDefaultNoLaunch() {
-        assertFalse(BackgroundSyncLauncher.shouldLaunchWhenNextOnline(mPrefs));
+        assertFalse(shouldLaunchWhenNextOnlineSync());
     }
 
     @SmallTest
     @Feature({"BackgroundSync"})
     public void testSetLaunchWhenNextOnline() {
-        assertFalse(BackgroundSyncLauncher.shouldLaunchWhenNextOnline(mPrefs));
-        mLauncher.setLaunchWhenNextOnline(true);
-        assertTrue(BackgroundSyncLauncher.shouldLaunchWhenNextOnline(mPrefs));
-        mLauncher.setLaunchWhenNextOnline(false);
-        assertFalse(BackgroundSyncLauncher.shouldLaunchWhenNextOnline(mPrefs));
+        assertFalse(shouldLaunchWhenNextOnlineSync());
+        mLauncher.setLaunchWhenNextOnline(mContext, true);
+        assertTrue(shouldLaunchWhenNextOnlineSync());
+        mLauncher.setLaunchWhenNextOnline(mContext, false);
+        assertFalse(shouldLaunchWhenNextOnlineSync());
     }
 
     @SmallTest
     @Feature({"BackgroundSync"})
     public void testNewLauncherDisablesNextOnline() {
-        mLauncher.setLaunchWhenNextOnline(true);
-        assertTrue(BackgroundSyncLauncher.shouldLaunchWhenNextOnline(mPrefs));
+        mLauncher.setLaunchWhenNextOnline(mContext, true);
+        assertTrue(shouldLaunchWhenNextOnlineSync());
 
         // Simulate restarting the browser by deleting the launcher and creating a new one.
         deleteLauncherInstance();
         mLauncher = BackgroundSyncLauncher.create(mContext);
-        assertFalse(BackgroundSyncLauncher.shouldLaunchWhenNextOnline(mPrefs));
-    }
-
-    @SmallTest
-    @Feature({"BackgroundSync"})
-    public void testFireWhenScheduled() {
-        mLauncher.setLaunchWhenNextOnline(true);
-        deleteLauncherInstance();
-
-        mLauncherServiceReceiver.setOnline(true);
-        startOnReceiveAndVerify(true);
-    }
-
-    @SmallTest
-    @Feature({"BackgroundSync"})
-    public void testNoFireWhenNotScheduled() {
-        mLauncher.setLaunchWhenNextOnline(false);
-        deleteLauncherInstance();
-
-        mLauncherServiceReceiver.setOnline(true);
-        startOnReceiveAndVerify(false);
+        assertFalse(shouldLaunchWhenNextOnlineSync());
     }
 
     @SmallTest
     @Feature({"BackgroundSync"})
     public void testNoFireWhenInstanceExists() {
-        mLauncher.setLaunchWhenNextOnline(true);
+        mLauncher.setLaunchWhenNextOnline(mContext, true);
         mLauncherServiceReceiver.setOnline(true);
         startOnReceiveAndVerify(false);
 
@@ -142,7 +144,7 @@
     @SmallTest
     @Feature({"BackgroundSync"})
     public void testReceiverOffline() {
-        mLauncher.setLaunchWhenNextOnline(true);
+        mLauncher.setLaunchWhenNextOnline(mContext, true);
         mLauncherServiceReceiver.setOnline(false);
         deleteLauncherInstance();
         startOnReceiveAndVerify(false);
@@ -151,7 +153,7 @@
     @SmallTest
     @Feature({"BackgroundSync"})
     public void testReceiverOnline() {
-        mLauncher.setLaunchWhenNextOnline(true);
+        mLauncher.setLaunchWhenNextOnline(mContext, true);
         mLauncherServiceReceiver.setOnline(true);
         deleteLauncherInstance();
         startOnReceiveAndVerify(true);