OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 | 9 |
10 import org.chromium.base.ApplicationStatus; | |
9 import org.chromium.base.Callback; | 11 import org.chromium.base.Callback; |
10 import org.chromium.base.Log; | 12 import org.chromium.base.Log; |
11 import org.chromium.base.library_loader.LibraryProcessType; | 13 import org.chromium.base.SysUtils; |
12 import org.chromium.base.library_loader.ProcessInitException; | 14 import org.chromium.base.VisibleForTesting; |
13 import org.chromium.chrome.browser.init.ChromeBrowserInitializer; | 15 import org.chromium.chrome.browser.background_task_scheduler.NativeBackgroundTas k; |
14 import org.chromium.chrome.browser.offlinepages.interfaces.BackgroundSchedulerPr ocessor; | |
15 import org.chromium.components.background_task_scheduler.BackgroundTask; | |
16 import org.chromium.components.background_task_scheduler.BackgroundTask.TaskFini shedCallback; | 16 import org.chromium.components.background_task_scheduler.BackgroundTask.TaskFini shedCallback; |
17 import org.chromium.components.background_task_scheduler.TaskIds; | 17 import org.chromium.components.background_task_scheduler.TaskIds; |
18 import org.chromium.components.background_task_scheduler.TaskParameters; | 18 import org.chromium.components.background_task_scheduler.TaskParameters; |
19 import org.chromium.content.browser.BrowserStartupController; | |
20 | 19 |
21 /** | 20 /** |
22 * Handles servicing background offlining requests coming via background_task_sc heduler component. | 21 * Handles servicing of background offlining requests coming via background_task _scheduler |
22 * component. | |
23 */ | 23 */ |
24 public class OfflineBackgroundTask implements BackgroundTask { | 24 public class OfflineBackgroundTask extends NativeBackgroundTask { |
25 private static final String TAG = "OPBackgroundTask"; | 25 private static final String TAG = "OfflineBkgrndTask"; |
26 | 26 |
27 BackgroundSchedulerProcessor mBackgroundProcessor; | 27 BackgroundSchedulerProcessor mBackgroundProcessor; |
28 | 28 |
29 public OfflineBackgroundTask() { | 29 public OfflineBackgroundTask() { |
30 mBackgroundProcessor = new BackgroundSchedulerProcessorImpl(); | 30 mBackgroundProcessor = new BackgroundSchedulerProcessor(); |
31 } | 31 } |
32 | 32 |
33 @Override | 33 @Override |
34 public boolean onStartTask( | 34 @StartBeforeNativeResult |
35 protected int onStartTaskBeforeNativeLoaded( | |
35 Context context, TaskParameters taskParameters, TaskFinishedCallback callback) { | 36 Context context, TaskParameters taskParameters, TaskFinishedCallback callback) { |
36 assert taskParameters.getTaskId() == TaskIds.OFFLINE_PAGES_BACKGROUND_JO B_ID; | 37 assert taskParameters.getTaskId() == TaskIds.OFFLINE_PAGES_BACKGROUND_JO B_ID; |
37 | 38 |
38 // Ensuring that native potion of the browser is launched. | 39 if (!checkConditions(context, taskParameters.getExtras())) { |
39 launchBrowserIfNecessary(context); | 40 return RESCHEDULE; |
41 } | |
40 | 42 |
41 return BackgroundOfflinerTask.startBackgroundRequestsImpl( | 43 return LOAD_NATIVE; |
42 mBackgroundProcessor, context, taskParameters.getExtras(), wrapC allback(callback)); | |
43 } | 44 } |
44 | 45 |
45 @Override | 46 @Override |
46 public boolean onStopTask(Context context, TaskParameters taskParameters) { | 47 protected void onStartTaskWithNative( |
48 Context context, TaskParameters taskParameters, TaskFinishedCallback callback) { | |
49 assert taskParameters.getTaskId() == TaskIds.OFFLINE_PAGES_BACKGROUND_JO B_ID; | |
50 | |
51 if (!startScheduledProcessing(mBackgroundProcessor, context, taskParamet ers.getExtras(), | |
52 wrapCallback(callback))) { | |
53 callback.taskFinished(true); | |
54 return; | |
55 } | |
56 | |
57 // Set up backup scheduled task in case processing is killed before Requ estCoordinator | |
58 // has a chance to reschedule base on remaining work. | |
59 BackgroundScheduler.getInstance().scheduleBackup( | |
60 TaskExtrasPacker.unpackTriggerConditionsFromBundle(taskParameter s.getExtras()), | |
61 BackgroundScheduler.FIVE_MINUTES_IN_MILLISECONDS); | |
62 } | |
63 | |
64 @Override | |
65 protected boolean onStopTaskBeforeNativeLoaded(Context context, TaskParamete rs taskParameters) { | |
66 assert taskParameters.getTaskId() == TaskIds.OFFLINE_PAGES_BACKGROUND_JO B_ID; | |
67 | |
68 return true; | |
Pete Williamson
2017/05/24 21:41:03
Should this be doing something besides returning t
fgorski
2017/05/24 23:10:12
Nope. There is nothing to do if native was not imp
| |
69 } | |
70 | |
71 @Override | |
72 protected boolean onStopTaskWithNative(Context context, TaskParameters taskP arameters) { | |
73 assert taskParameters.getTaskId() == TaskIds.OFFLINE_PAGES_BACKGROUND_JO B_ID; | |
74 | |
47 return mBackgroundProcessor.stopScheduledProcessing(); | 75 return mBackgroundProcessor.stopScheduledProcessing(); |
48 } | 76 } |
49 | 77 |
50 @Override | 78 @Override |
51 public void reschedule(Context context) { | 79 public void reschedule(Context context) { |
52 BackgroundScheduler.getInstance(context).rescheduleOfflinePagesTasksOnUp grade(); | 80 BackgroundScheduler.getInstance().reschedule(); |
53 } | 81 } |
54 | 82 |
55 /** Wraps the callback for code reuse */ | 83 /** Wraps the callback for code reuse */ |
56 private Callback<Boolean> wrapCallback(final TaskFinishedCallback callback) { | 84 private Callback<Boolean> wrapCallback(final TaskFinishedCallback callback) { |
57 return new Callback<Boolean>() { | 85 return new Callback<Boolean>() { |
58 @Override | 86 @Override |
59 public void onResult(Boolean result) { | 87 public void onResult(Boolean result) { |
60 callback.taskFinished(result); | 88 callback.taskFinished(result); |
61 } | 89 } |
62 }; | 90 }; |
63 } | 91 } |
64 | 92 |
65 private static void launchBrowserIfNecessary(Context context) { | 93 /** |
66 if (BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER) | 94 * Starts scheduled processing and reports UMA. This method does not check f or current |
67 .isStartupSuccessfullyCompleted()) { | 95 * conditions and should be used together with {@link #checkConditions} to e nsure that it |
68 return; | 96 * performs the tasks only when it is supposed to. |
97 * | |
98 * @returns Whether processing will be carried out and completion will be in dicated through a | |
99 * callback. | |
100 */ | |
101 @VisibleForTesting | |
102 static boolean startScheduledProcessing(BackgroundSchedulerProcessor bridge, Context context, | |
103 Bundle taskExtras, Callback<Boolean> callback) { | |
104 // Gather UMA data to measure how often the user's machine is amenable t o background | |
105 // loading when we wake to do a task. | |
106 long taskScheduledTimeMillis = TaskExtrasPacker.unpackTimeFromBundle(tas kExtras); | |
107 OfflinePageUtils.recordWakeupUMA(context, taskScheduledTimeMillis); | |
108 | |
109 DeviceConditions deviceConditions = DeviceConditions.getCurrentCondition s(context); | |
110 return bridge.startScheduledProcessing(deviceConditions, callback); | |
Pete Williamson
2017/05/24 21:41:03
By the way, not that I'm suggesting it, but one op
fgorski
2017/05/24 23:10:12
This is probably a good material for a follow up,
| |
111 } | |
112 | |
113 /** @returns Whether conditions for running the tasks are met. */ | |
114 @VisibleForTesting | |
115 static boolean checkConditions(Context context, Bundle taskExtras) { | |
116 TriggerConditions triggerConditions = | |
117 TaskExtrasPacker.unpackTriggerConditionsFromBundle(taskExtras); | |
118 | |
119 DeviceConditions deviceConditions = DeviceConditions.getCurrentCondition s(context); | |
120 if (!areBatteryConditionsMet(deviceConditions, triggerConditions)) { | |
Pete Williamson
2017/05/24 21:41:03
This seems to run counter to the comment at the to
fgorski
2017/05/24 23:10:12
We are inside of checkConditions() here, starting
| |
121 Log.d(TAG, "Battery percentage is lower than minimum to start proces sing"); | |
122 return false; | |
69 } | 123 } |
70 | 124 |
71 // TODO(fgorski): This method is taken from ChromeBackgroundService as a local fix and will | 125 if (!isSvelteConditionsMet()) { |
72 // be removed with BackgroundTaskScheduler supporting GcmNetworkManager scheduling. | 126 Log.d(TAG, "Application visible on low-end device so deferring backg round processing"); |
73 try { | 127 return false; |
74 ChromeBrowserInitializer.getInstance(context).handleSynchronousStart up(); | |
75 } catch (ProcessInitException e) { | |
76 Log.e(TAG, "ProcessInitException while starting the browser process. "); | |
77 // Since the library failed to initialize nothing in the application can work, so kill | |
78 // the whole application not just the activity. | |
79 System.exit(-1); | |
80 } | 128 } |
129 | |
130 return true; | |
131 } | |
132 | |
133 /** Whether battery conditions (on power and enough battery percentage) are met. */ | |
134 private static boolean areBatteryConditionsMet( | |
135 DeviceConditions deviceConditions, TriggerConditions triggerConditio ns) { | |
136 return deviceConditions.isPowerConnected() | |
137 || (deviceConditions.getBatteryPercentage() | |
138 >= triggerConditions.getMinimumBatteryPercentage()); | |
139 } | |
140 | |
141 /** Whether there are no visible activities when on Svelte. */ | |
142 private static boolean isSvelteConditionsMet() { | |
143 return !SysUtils.isLowEndDevice() || !ApplicationStatus.hasVisibleActivi ties(); | |
81 } | 144 } |
82 } | 145 } |
OLD | NEW |