[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);