Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/precache/PrecacheService.java

Issue 1031003003: precache: Move the java files into //components/precache/android (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/precache/PrecacheService.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/precache/PrecacheService.java b/chrome/android/java/src/org/chromium/chrome/browser/precache/PrecacheService.java
new file mode 100644
index 0000000000000000000000000000000000000000..09a557be3d0995a6133972c2cf629ee69b6e4c0b
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/precache/PrecacheService.java
@@ -0,0 +1,211 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.precache;
+
+import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.os.IBinder;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.util.Log;
+
+import org.chromium.base.VisibleForTesting;
+import org.chromium.base.annotations.SuppressFBWarnings;
+import org.chromium.base.library_loader.LibraryProcessType;
+import org.chromium.base.library_loader.ProcessInitException;
+import org.chromium.components.precache.DeviceState;
+import org.chromium.content.browser.BrowserStartupController;
+
+/**
+ * Background service that runs while Chrome is precaching resources. Precaching is only done while
+ * the device is connected to power, Wi-Fi, and the device is not interactive (e.g., the screen is
+ * off. This is a sticky service that is started when the {@link PrecacheServiceLauncher}
+ * determines that conditions are right for precaching. Once started, this service runs until
+ * either precaching finishes successfully, or the conditions are no longer met.
+ */
+public class PrecacheService extends Service {
+ private static final String TAG = "PrecacheService";
+
+ public static final String ACTION_START_PRECACHE =
+ "org.chromium.chrome.browser.precache.PrecacheService.START_PRECACHE";
+
+ /** Wakelock that is held while precaching is in progress. */
+ private WakeLock mPrecachingWakeLock;
+
+ /** True if there is a precache in progress. */
+ private boolean mIsPrecaching = false;
+
+ @VisibleForTesting
+ boolean isPrecaching() {
+ return mIsPrecaching;
+ }
+
+ private DeviceState mDeviceState = DeviceState.getInstance();
+
+ @VisibleForTesting
+ void setDeviceState(DeviceState deviceState) {
+ mDeviceState = deviceState;
+ }
+
+
+ /** Receiver that will be notified when conditions become wrong for precaching. */
+ private final BroadcastReceiver mDeviceStateReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (mIsPrecaching && (mDeviceState.isInteractive(context)
+ || !mDeviceState.isPowerConnected(context)
+ || !mDeviceState.isWifiAvailable(context))) {
+ cancelPrecaching();
+ }
+ }
+ };
+
+ @VisibleForTesting
+ BroadcastReceiver getDeviceStateReceiver() {
+ return mDeviceStateReceiver;
+ }
+
+ @VisibleForTesting
+ void handlePrecacheCompleted() {
+ if (mIsPrecaching) finishPrecaching();
+ }
+
+ /** PrecacheLauncher used to run precaching. */
+ private PrecacheLauncher mPrecacheLauncher = new PrecacheLauncher() {
+ @Override
+ protected void onPrecacheCompleted() {
+ handlePrecacheCompleted();
+ }
+ };
+
+ @VisibleForTesting
+ void setPrecacheLauncher(PrecacheLauncher precacheLauncher) {
+ mPrecacheLauncher = precacheLauncher;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ registerDeviceStateReceiver();
+ }
+
+ @Override
+ public void onDestroy() {
+ if (mIsPrecaching) cancelPrecaching();
+
+ unregisterReceiver(mDeviceStateReceiver);
+ mPrecacheLauncher.destroy();
+ releasePrecachingWakeLock();
+
+ super.onDestroy();
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ try {
+ if (intent != null && ACTION_START_PRECACHE.equals(intent.getAction())
+ && !mIsPrecaching) {
+ // Only start precaching if precaching is not already in progress.
+ startPrecaching();
+ }
+ } finally {
+ PrecacheServiceLauncher.releaseWakeLock();
+ }
+ // The PrecacheService should only be running while precaching is in progress. Return
+ // {@link Service.START_STICKY} if precaching is in progress to keep the service running;
+ // otherwise, return {@link Service.START_NOT_STICKY} to cause the service to stop once it
+ // is done processing commands sent to it.
+ return mIsPrecaching ? START_STICKY : START_NOT_STICKY;
+ }
+
+ /** PrecacheService does not support binding. */
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ /** Attempt to start up the browser processes and load the native libraries. */
+ @SuppressFBWarnings("DM_EXIT")
+ @VisibleForTesting
+ void prepareNativeLibraries() {
+ try {
+ BrowserStartupController.get(getApplicationContext(),
+ LibraryProcessType.PROCESS_BROWSER)
+ .startBrowserProcessesSync(false);
+ } catch (ProcessInitException e) {
+ Log.e(TAG, "ProcessInitException while starting the browser process");
+ // Since the library failed to initialize nothing in the application
+ // can work, so kill the whole application not just the activity.
+ System.exit(-1);
+ }
+ }
+
+ /** Begin a precache cycle. */
+ private void startPrecaching() {
+ Log.v(TAG, "Start precaching");
+ prepareNativeLibraries();
+ mIsPrecaching = true;
+ acquirePrecachingWakeLock();
+
+ // In certain cases, the PrecacheLauncher will skip precaching entirely and call
+ // finishPrecaching() before this call to mPrecacheLauncher.start() returns, so the call to
+ // mPrecacheLauncher.start() must happen after acquiring the wake lock to ensure that the
+ // wake lock is released properly.
+ mPrecacheLauncher.start();
+ }
+
+ /** End a precache cycle. */
+ private void finishPrecaching() {
+ Log.v(TAG, "Finish precaching");
+ shutdownPrecaching();
+ }
+
+ /** Cancel a precache cycle. */
+ private void cancelPrecaching() {
+ Log.v(TAG, "Cancel precaching");
+ prepareNativeLibraries();
+ mPrecacheLauncher.cancel();
+
+ shutdownPrecaching();
+ }
+
+ /**
+ * Update state to indicate that precaching is no longer in progress, and stop the service.
+ */
+ private void shutdownPrecaching() {
+ mIsPrecaching = false;
+ releasePrecachingWakeLock();
+ stopSelf();
+ }
+
+ /** Register a BroadcastReceiver to detect when conditions become wrong for precaching. */
+ private void registerDeviceStateReceiver() {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
+ filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ registerReceiver(mDeviceStateReceiver, filter);
+ }
+
+ /** Acquire the precaching WakeLock. */
+ private void acquirePrecachingWakeLock() {
+ if (mPrecachingWakeLock == null) {
+ PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
+ mPrecachingWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+ }
+ mPrecachingWakeLock.acquire();
+ }
+
+ /** Release the precaching WakeLock if it is held. */
+ private void releasePrecachingWakeLock() {
+ if (mPrecachingWakeLock != null && mPrecachingWakeLock.isHeld()) {
+ mPrecachingWakeLock.release();
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698