| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.offlinepages; | 5 package org.chromium.chrome.browser.offlinepages; |
| 6 | 6 |
| 7 import android.content.Context; | 7 import android.content.Context; |
| 8 import android.os.Bundle; | 8 import android.os.Bundle; |
| 9 | 9 |
| 10 import org.chromium.base.ApplicationStatus; | 10 import org.chromium.base.ApplicationStatus; |
| 11 import org.chromium.base.Callback; | 11 import org.chromium.base.Callback; |
| 12 import org.chromium.base.Log; | 12 import org.chromium.base.Log; |
| 13 import org.chromium.base.SysUtils; | 13 import org.chromium.base.SysUtils; |
| 14 import org.chromium.base.VisibleForTesting; | |
| 15 import org.chromium.chrome.browser.ChromeBackgroundServiceWaiter; | 14 import org.chromium.chrome.browser.ChromeBackgroundServiceWaiter; |
| 16 import org.chromium.chrome.browser.offlinepages.interfaces.BackgroundSchedulerPr
ocessor; | 15 import org.chromium.chrome.browser.offlinepages.interfaces.BackgroundSchedulerPr
ocessor; |
| 17 | 16 |
| 18 /** | 17 /** |
| 19 * Handles servicing of background offlining requests coming via the GcmNetworkM
anager. | 18 * Handles servicing of background offlining requests coming via the GcmNetworkM
anager. |
| 20 */ | 19 */ |
| 21 public class BackgroundOfflinerTask { | 20 public class BackgroundOfflinerTask { |
| 22 private static final String TAG = "BGOfflinerTask"; | 21 private static final String TAG = "BGOfflinerTask"; |
| 23 private static final long DEFER_START_SECONDS = 5 * 60; | 22 private static final long DEFER_START_SECONDS = 5 * 60; |
| 24 | 23 |
| 25 public BackgroundOfflinerTask(BackgroundSchedulerProcessor bridge) { | 24 public BackgroundOfflinerTask(BackgroundSchedulerProcessor bridge) { |
| 26 mBridge = bridge; | 25 mBridge = bridge; |
| 27 } | 26 } |
| 28 | 27 |
| 29 private final BackgroundSchedulerProcessor mBridge; | 28 private final BackgroundSchedulerProcessor mBridge; |
| 30 | 29 |
| 31 /** | 30 /** |
| 32 * Triggers processing of background offlining requests. This is called whe
n | 31 * Triggers processing of background offlining requests. This is called whe
n |
| 33 * system conditions are appropriate for background offlining, typically fro
m the | 32 * system conditions are appropriate for background offlining, typically fro
m the |
| 34 * GcmTaskService onRunTask() method. In response, we will start the | 33 * GcmTaskService onRunTask() method. In response, we will start the |
| 35 * task processing by passing the call along to the C++ RequestCoordinator. | 34 * task processing by passing the call along to the C++ RequestCoordinator. |
| 36 * Also starts UMA collection. | 35 * Also starts UMA collection. |
| 37 * | 36 * |
| 38 * @returns true for success | 37 * @returns true for success |
| 39 */ | 38 */ |
| 40 public boolean startBackgroundRequests(Context context, Bundle bundle, | 39 public void startBackgroundRequests( |
| 41 ChromeBackgroundServiceWaiter waiter)
{ | 40 Context context, Bundle bundle, final ChromeBackgroundServiceWaiter
waiter) { |
| 41 // Complete the wait if background request processing was not started. |
| 42 // If background processing was started, completion is going to be handl
ed by callback. |
| 43 if (!startBackgroundRequestsImpl(context, bundle, waiter)) { |
| 44 waiter.onWaitDone(); |
| 45 } |
| 46 } |
| 47 |
| 48 /** |
| 49 * Triggers processing of background offlining requests. This is called whe
n |
| 50 * system conditions are appropriate for background offlining, typically fro
m the |
| 51 * GcmTaskService onRunTask() method. In response, we will start the |
| 52 * task processing by passing the call along to the C++ RequestCoordinator. |
| 53 * Also starts UMA collection. |
| 54 * |
| 55 * @returns true for success |
| 56 */ |
| 57 private boolean startBackgroundRequestsImpl( |
| 58 Context context, Bundle bundle, final ChromeBackgroundServiceWaiter
waiter) { |
| 42 // Set up backup scheduled task in case processing is killed before Requ
estCoordinator | 59 // Set up backup scheduled task in case processing is killed before Requ
estCoordinator |
| 43 // has a chance to reschedule base on remaining work. | 60 // has a chance to reschedule base on remaining work. |
| 44 TriggerConditions previousTriggerConditions = | 61 TriggerConditions previousTriggerConditions = |
| 45 TaskExtrasPacker.unpackTriggerConditionsFromBundle(bundle); | 62 TaskExtrasPacker.unpackTriggerConditionsFromBundle(bundle); |
| 46 BackgroundScheduler.backupSchedule(context, previousTriggerConditions, D
EFER_START_SECONDS); | 63 BackgroundScheduler.backupSchedule(context, previousTriggerConditions, D
EFER_START_SECONDS); |
| 47 | 64 |
| 48 DeviceConditions currentConditions = OfflinePageUtils.getDeviceCondition
s(context); | 65 DeviceConditions currentConditions = OfflinePageUtils.getDeviceCondition
s(context); |
| 49 if (!currentConditions.isPowerConnected() | 66 if (!currentConditions.isPowerConnected() |
| 50 && currentConditions.getBatteryPercentage() | 67 && currentConditions.getBatteryPercentage() |
| 51 < previousTriggerConditions.getMinimumBatteryPercentage(
)) { | 68 < previousTriggerConditions.getMinimumBatteryPercentage(
)) { |
| 52 Log.d(TAG, "Battery percentage is lower than minimum to start proces
sing"); | 69 Log.d(TAG, "Battery percentage is lower than minimum to start proces
sing"); |
| 53 return false; | 70 return false; |
| 54 } | 71 } |
| 55 | 72 |
| 56 if (SysUtils.isLowEndDevice() && ApplicationStatus.hasVisibleActivities(
)) { | 73 if (SysUtils.isLowEndDevice() && ApplicationStatus.hasVisibleActivities(
)) { |
| 57 Log.d(TAG, "Application visible on low-end device so deferring backg
round processing"); | 74 Log.d(TAG, "Application visible on low-end device so deferring backg
round processing"); |
| 58 return false; | 75 return false; |
| 59 } | 76 } |
| 60 | 77 |
| 61 // Now initiate processing. | |
| 62 processBackgroundRequests(bundle, currentConditions, waiter); | |
| 63 | |
| 64 // Gather UMA data to measure how often the user's machine is amenable t
o background | 78 // Gather UMA data to measure how often the user's machine is amenable t
o background |
| 65 // loading when we wake to do a task. | 79 // loading when we wake to do a task. |
| 66 long taskScheduledTimeMillis = TaskExtrasPacker.unpackTimeFromBundle(bun
dle); | 80 long taskScheduledTimeMillis = TaskExtrasPacker.unpackTimeFromBundle(bun
dle); |
| 67 OfflinePageUtils.recordWakeupUMA(context, taskScheduledTimeMillis); | 81 OfflinePageUtils.recordWakeupUMA(context, taskScheduledTimeMillis); |
| 68 | 82 |
| 69 return true; | 83 return mBridge.startScheduledProcessing(currentConditions, createCallbac
k(waiter)); |
| 70 } | 84 } |
| 71 | 85 |
| 72 /** | 86 private Callback<Boolean> createCallback(final ChromeBackgroundServiceWaiter
waiter) { |
| 73 * Triggers processing of background offlining requests. | 87 return new Callback<Boolean>() { |
| 74 */ | 88 /** Callback releasing the wakelock once background work concludes.
*/ |
| 75 // TODO(petewil): Change back to private when UMA works in the test, and tes
t | |
| 76 // startBackgroundRequests instead of this method. | |
| 77 @VisibleForTesting | |
| 78 public void processBackgroundRequests( | |
| 79 Bundle bundle, DeviceConditions deviceConditions, | |
| 80 final ChromeBackgroundServiceWaiter waiter) { | |
| 81 // TODO(petewil): Nothing is holding the Wake Lock. We need some soluti
on to | |
| 82 // keep hold of it. Options discussed so far are having a fresh set of
functions | |
| 83 // to grab and release a countdown latch, or holding onto the wake lock
ourselves, | |
| 84 // or grabbing the wake lock and then starting chrome and running | |
| 85 // startScheduledProcessing on the UI thread. | |
| 86 | |
| 87 // TODO(petewil): Decode the TriggerConditions from the bundle. | |
| 88 | |
| 89 Callback<Boolean> callback = new Callback<Boolean>() { | |
| 90 /** | |
| 91 * Callback function which indicates completion of background work. | |
| 92 * @param result - true if work was actually done (used for UMA). | |
| 93 */ | |
| 94 @Override | 89 @Override |
| 95 public void onResult(Boolean result) { | 90 public void onResult(Boolean result) { |
| 91 Log.d(TAG, "onProcessingDone"); |
| 96 // Release the wake lock. | 92 // Release the wake lock. |
| 97 Log.d(TAG, "onProcessingDone"); | |
| 98 waiter.onWaitDone(); | 93 waiter.onWaitDone(); |
| 99 } | 94 } |
| 100 }; | 95 }; |
| 101 | |
| 102 // Pass the activation on to the bridge to the C++ RequestCoordinator. | |
| 103 if (!mBridge.startScheduledProcessing(deviceConditions, callback)) { | |
| 104 // Processing not started currently. Let callback know. | |
| 105 callback.onResult(false); | |
| 106 } | |
| 107 } | 96 } |
| 108 } | 97 } |
| OLD | NEW |