[NTP Snippets] Scheduler: Fetch on Wifi (without charging) only 6AM-10PM
BUG=587857 Review URL: https://codereview.chromium.org/1869323003 Cr-Commit-Position: refs/heads/master@{#388231}
This commit is contained in:
chrome
android
java
src
org
chromium
chrome
browser
javatests
src
org
chromium
chrome
browser
components/ntp_snippets
@@ -53,6 +53,10 @@ public class ChromeBackgroundService extends GcmTaskService {
|
|||||||
handleFetchSnippets(context);
|
handleFetchSnippets(context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SnippetsLauncher.TASK_TAG_RESCHEDULE:
|
||||||
|
handleRescheduleSnippets(context);
|
||||||
|
break;
|
||||||
|
|
||||||
case PrecacheController.PERIODIC_TASK_TAG:
|
case PrecacheController.PERIODIC_TASK_TAG:
|
||||||
case PrecacheController.CONTINUATION_TASK_TAG:
|
case PrecacheController.CONTINUATION_TASK_TAG:
|
||||||
handlePrecache(context, params.getTag());
|
handlePrecache(context, params.getTag());
|
||||||
@@ -91,6 +95,18 @@ public class ChromeBackgroundService extends GcmTaskService {
|
|||||||
SnippetsBridge.fetchSnippets();
|
SnippetsBridge.fetchSnippets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleRescheduleSnippets(Context context) {
|
||||||
|
if (!SnippetsLauncher.hasInstance()) {
|
||||||
|
launchBrowser(context);
|
||||||
|
}
|
||||||
|
rescheduleSnippets();
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
protected void rescheduleSnippets() {
|
||||||
|
SnippetsBridge.rescheduleFetching();
|
||||||
|
}
|
||||||
|
|
||||||
private void handlePrecache(Context context, String tag) {
|
private void handlePrecache(Context context, String tag) {
|
||||||
if (!hasPrecacheInstance()) {
|
if (!hasPrecacheInstance()) {
|
||||||
launchBrowser(context);
|
launchBrowser(context);
|
||||||
|
@@ -53,6 +53,14 @@ public class SnippetsBridge {
|
|||||||
nativeFetchSnippets();
|
nativeFetchSnippets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reschedules the fetching of snippets. Used to support different fetching intervals for
|
||||||
|
* different times of day.
|
||||||
|
*/
|
||||||
|
public static void rescheduleFetching() {
|
||||||
|
nativeRescheduleFetching();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tells the native service to discard a snippet. It will be removed from the native side
|
* Tells the native service to discard a snippet. It will be removed from the native side
|
||||||
* storage and will also be discarded from subsequent fetch results.
|
* storage and will also be discarded from subsequent fetch results.
|
||||||
@@ -98,6 +106,7 @@ public class SnippetsBridge {
|
|||||||
private native long nativeInit(Profile profile);
|
private native long nativeInit(Profile profile);
|
||||||
private native void nativeDestroy(long nativeNTPSnippetsBridge);
|
private native void nativeDestroy(long nativeNTPSnippetsBridge);
|
||||||
private static native void nativeFetchSnippets();
|
private static native void nativeFetchSnippets();
|
||||||
|
private static native void nativeRescheduleFetching();
|
||||||
private native void nativeDiscardSnippet(long nativeNTPSnippetsBridge, String snippetUrl);
|
private native void nativeDiscardSnippet(long nativeNTPSnippetsBridge, String snippetUrl);
|
||||||
private native void nativeSetObserver(long nativeNTPSnippetsBridge, SnippetsBridge bridge);
|
private native void nativeSetObserver(long nativeNTPSnippetsBridge, SnippetsBridge bridge);
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,7 @@ package org.chromium.chrome.browser.ntp.snippets;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import com.google.android.gms.gcm.GcmNetworkManager;
|
import com.google.android.gms.gcm.GcmNetworkManager;
|
||||||
|
import com.google.android.gms.gcm.OneoffTask;
|
||||||
import com.google.android.gms.gcm.PeriodicTask;
|
import com.google.android.gms.gcm.PeriodicTask;
|
||||||
import com.google.android.gms.gcm.Task;
|
import com.google.android.gms.gcm.Task;
|
||||||
|
|
||||||
@@ -18,6 +19,8 @@ import org.chromium.chrome.browser.ChromeBackgroundService;
|
|||||||
import org.chromium.chrome.browser.externalauth.ExternalAuthUtils;
|
import org.chromium.chrome.browser.externalauth.ExternalAuthUtils;
|
||||||
import org.chromium.chrome.browser.externalauth.UserRecoverableErrorHandler;
|
import org.chromium.chrome.browser.externalauth.UserRecoverableErrorHandler;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link SnippetsLauncher} singleton is created and owned by the C++ browser.
|
* The {@link SnippetsLauncher} singleton is created and owned by the C++ browser.
|
||||||
*
|
*
|
||||||
@@ -26,10 +29,15 @@ import org.chromium.chrome.browser.externalauth.UserRecoverableErrorHandler;
|
|||||||
public class SnippetsLauncher {
|
public class SnippetsLauncher {
|
||||||
private static final String TAG = "SnippetsLauncher";
|
private static final String TAG = "SnippetsLauncher";
|
||||||
|
|
||||||
|
// Task tags for fetching snippets.
|
||||||
public static final String TASK_TAG_WIFI_CHARGING = "FetchSnippetsWifiCharging";
|
public static final String TASK_TAG_WIFI_CHARGING = "FetchSnippetsWifiCharging";
|
||||||
public static final String TASK_TAG_WIFI = "FetchSnippetsWifi";
|
public static final String TASK_TAG_WIFI = "FetchSnippetsWifi";
|
||||||
public static final String TASK_TAG_FALLBACK = "FetchSnippetsFallback";
|
public static final String TASK_TAG_FALLBACK = "FetchSnippetsFallback";
|
||||||
|
|
||||||
|
// Task tag for re-scheduling the snippet fetching. This is used to support different fetching
|
||||||
|
// intervals during different times of day.
|
||||||
|
public static final String TASK_TAG_RESCHEDULE = "RescheduleSnippets";
|
||||||
|
|
||||||
// The instance of SnippetsLauncher currently owned by a C++ SnippetsLauncherAndroid, if any.
|
// The instance of SnippetsLauncher currently owned by a C++ SnippetsLauncherAndroid, if any.
|
||||||
// If it is non-null then the browser is running.
|
// If it is non-null then the browser is running.
|
||||||
private static SnippetsLauncher sInstance;
|
private static SnippetsLauncher sInstance;
|
||||||
@@ -90,7 +98,7 @@ public class SnippetsLauncher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PeriodicTask buildTask(
|
private static PeriodicTask buildFetchTask(
|
||||||
String tag, long periodSeconds, int requiredNetwork, boolean requiresCharging) {
|
String tag, long periodSeconds, int requiredNetwork, boolean requiresCharging) {
|
||||||
return new PeriodicTask.Builder()
|
return new PeriodicTask.Builder()
|
||||||
.setService(ChromeBackgroundService.class)
|
.setService(ChromeBackgroundService.class)
|
||||||
@@ -103,21 +111,51 @@ public class SnippetsLauncher {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static OneoffTask buildRescheduleTask(Date date) {
|
||||||
|
Date now = new Date();
|
||||||
|
// Convert from milliseconds to seconds, rounding up.
|
||||||
|
long delaySeconds = (now.getTime() - date.getTime() + 999) / 1000;
|
||||||
|
final long intervalSeconds = 15 * 60;
|
||||||
|
return new OneoffTask.Builder()
|
||||||
|
.setService(ChromeBackgroundService.class)
|
||||||
|
.setTag(TASK_TAG_RESCHEDULE)
|
||||||
|
.setExecutionWindow(delaySeconds, delaySeconds + intervalSeconds)
|
||||||
|
.setRequiredNetwork(Task.NETWORK_STATE_ANY)
|
||||||
|
.setRequiresCharging(false)
|
||||||
|
.setPersisted(true)
|
||||||
|
.setUpdateCurrent(true)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scheduleOrCancelFetchTask(
|
||||||
|
String taskTag, long period, int requiredNetwork, boolean requiresCharging) {
|
||||||
|
if (period > 0) {
|
||||||
|
mScheduler.schedule(buildFetchTask(taskTag, period, requiredNetwork, requiresCharging));
|
||||||
|
} else {
|
||||||
|
mScheduler.cancelTask(taskTag, ChromeBackgroundService.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@CalledByNative
|
@CalledByNative
|
||||||
private boolean schedule(
|
private boolean schedule(long periodWifiChargingSeconds, long periodWifiSeconds,
|
||||||
long periodWifiChargingSeconds, long periodWifiSeconds, long periodFallbackSeconds) {
|
long periodFallbackSeconds, long rescheduleTime) {
|
||||||
if (!mGCMEnabled) return false;
|
if (!mGCMEnabled) return false;
|
||||||
Log.d(TAG, "Scheduling: " + periodWifiChargingSeconds + " " + periodWifiSeconds + " "
|
Log.d(TAG, "Scheduling: " + periodWifiChargingSeconds + " " + periodWifiSeconds + " "
|
||||||
+ periodFallbackSeconds);
|
+ periodFallbackSeconds);
|
||||||
// Google Play Services may not be up to date, if the application was not installed through
|
// Google Play Services may not be up to date, if the application was not installed through
|
||||||
// the Play Store. In this case, scheduling the task will fail silently.
|
// the Play Store. In this case, scheduling the task will fail silently.
|
||||||
try {
|
try {
|
||||||
mScheduler.schedule(buildTask(TASK_TAG_WIFI_CHARGING, periodWifiChargingSeconds,
|
scheduleOrCancelFetchTask(TASK_TAG_WIFI_CHARGING, periodWifiChargingSeconds,
|
||||||
Task.NETWORK_STATE_UNMETERED, true));
|
Task.NETWORK_STATE_UNMETERED, true);
|
||||||
mScheduler.schedule(buildTask(
|
scheduleOrCancelFetchTask(
|
||||||
TASK_TAG_WIFI, periodWifiSeconds, Task.NETWORK_STATE_UNMETERED, false));
|
TASK_TAG_WIFI, periodWifiSeconds, Task.NETWORK_STATE_UNMETERED, false);
|
||||||
mScheduler.schedule(buildTask(
|
scheduleOrCancelFetchTask(
|
||||||
TASK_TAG_FALLBACK, periodFallbackSeconds, Task.NETWORK_STATE_CONNECTED, false));
|
TASK_TAG_FALLBACK, periodFallbackSeconds, Task.NETWORK_STATE_CONNECTED, false);
|
||||||
|
if (rescheduleTime > 0) {
|
||||||
|
mScheduler.schedule(buildRescheduleTask(new Date(rescheduleTime)));
|
||||||
|
} else {
|
||||||
|
mScheduler.cancelTask(TASK_TAG_RESCHEDULE, ChromeBackgroundService.class);
|
||||||
|
}
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
// Disable GCM for the remainder of this session.
|
// Disable GCM for the remainder of this session.
|
||||||
mGCMEnabled = false;
|
mGCMEnabled = false;
|
||||||
@@ -131,18 +169,7 @@ public class SnippetsLauncher {
|
|||||||
private boolean unschedule() {
|
private boolean unschedule() {
|
||||||
if (!mGCMEnabled) return false;
|
if (!mGCMEnabled) return false;
|
||||||
Log.i(TAG, "Unscheduling");
|
Log.i(TAG, "Unscheduling");
|
||||||
try {
|
return schedule(0, 0, 0, 0);
|
||||||
mScheduler.cancelTask(TASK_TAG_WIFI_CHARGING, ChromeBackgroundService.class);
|
|
||||||
mScheduler.cancelTask(TASK_TAG_WIFI, ChromeBackgroundService.class);
|
|
||||||
mScheduler.cancelTask(TASK_TAG_FALLBACK, ChromeBackgroundService.class);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
// This occurs when SnippetsLauncherService is not found in the application
|
|
||||||
// manifest. Disable GCM for the remainder of this session.
|
|
||||||
mGCMEnabled = false;
|
|
||||||
// Return false so that the failure will be logged.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -29,6 +29,7 @@ public class ChromeBackgroundServiceTest extends InstrumentationTestCase {
|
|||||||
static class MockTaskService extends ChromeBackgroundService {
|
static class MockTaskService extends ChromeBackgroundService {
|
||||||
private boolean mDidLaunchBrowser = false;
|
private boolean mDidLaunchBrowser = false;
|
||||||
private boolean mDidFetchSnippets = false;
|
private boolean mDidFetchSnippets = false;
|
||||||
|
private boolean mDidRescheduleSnippets = false;
|
||||||
private boolean mHasPrecacheInstance = true;
|
private boolean mHasPrecacheInstance = true;
|
||||||
private boolean mPrecachingStarted = false;
|
private boolean mPrecachingStarted = false;
|
||||||
|
|
||||||
@@ -42,6 +43,11 @@ public class ChromeBackgroundServiceTest extends InstrumentationTestCase {
|
|||||||
mDidFetchSnippets = true;
|
mDidFetchSnippets = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void rescheduleSnippets() {
|
||||||
|
mDidRescheduleSnippets = true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean hasPrecacheInstance() {
|
protected boolean hasPrecacheInstance() {
|
||||||
return mHasPrecacheInstance;
|
return mHasPrecacheInstance;
|
||||||
@@ -58,13 +64,16 @@ public class ChromeBackgroundServiceTest extends InstrumentationTestCase {
|
|||||||
// to onRunTask, it will be enqueued after any possible call to launchBrowser, and we
|
// to onRunTask, it will be enqueued after any possible call to launchBrowser, and we
|
||||||
// can reliably check whether launchBrowser was called.
|
// can reliably check whether launchBrowser was called.
|
||||||
protected void checkExpectations(final boolean expectedLaunchBrowser,
|
protected void checkExpectations(final boolean expectedLaunchBrowser,
|
||||||
final boolean expectedPrecacheStarted, final boolean expectedFetchSnippets) {
|
final boolean expectedPrecacheStarted, final boolean expectedFetchSnippets,
|
||||||
|
final boolean expectedRescheduleSnippets) {
|
||||||
ThreadUtils.runOnUiThread(new Runnable() {
|
ThreadUtils.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
assertEquals("StartedService", expectedLaunchBrowser, mDidLaunchBrowser);
|
assertEquals("StartedService", expectedLaunchBrowser, mDidLaunchBrowser);
|
||||||
assertEquals("StartedPrecache", expectedPrecacheStarted, mPrecachingStarted);
|
assertEquals("StartedPrecache", expectedPrecacheStarted, mPrecachingStarted);
|
||||||
assertEquals("FetchedSnippets", expectedFetchSnippets, mDidFetchSnippets);
|
assertEquals("FetchedSnippets", expectedFetchSnippets, mDidFetchSnippets);
|
||||||
|
assertEquals("RescheduledSnippets", expectedRescheduleSnippets,
|
||||||
|
mDidRescheduleSnippets);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -95,51 +104,87 @@ public class ChromeBackgroundServiceTest extends InstrumentationTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void startOnRunTaskAndVerify(String taskTag, boolean shouldStart,
|
private void startOnRunTaskAndVerify(String taskTag, boolean shouldStart,
|
||||||
boolean shouldPrecache, boolean shouldFetchSnippets) {
|
boolean shouldPrecache, boolean shouldFetchSnippets, boolean shouldRescheduleSnippets) {
|
||||||
mTaskService.onRunTask(new TaskParams(taskTag));
|
mTaskService.onRunTask(new TaskParams(taskTag));
|
||||||
mTaskService.checkExpectations(shouldStart, shouldPrecache, shouldFetchSnippets);
|
mTaskService.checkExpectations(
|
||||||
|
shouldStart, shouldPrecache, shouldFetchSnippets, shouldRescheduleSnippets);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@Feature({"BackgroundSync"})
|
@Feature({"BackgroundSync"})
|
||||||
public void testBackgroundSyncNoLaunchBrowserWhenInstanceExists() {
|
public void testBackgroundSyncNoLaunchBrowserWhenInstanceExists() {
|
||||||
startOnRunTaskAndVerify(BackgroundSyncLauncher.TASK_TAG, false, false, false);
|
startOnRunTaskAndVerify(BackgroundSyncLauncher.TASK_TAG, false, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@Feature({"BackgroundSync"})
|
@Feature({"BackgroundSync"})
|
||||||
public void testBackgroundSyncLaunchBrowserWhenInstanceDoesNotExist() {
|
public void testBackgroundSyncLaunchBrowserWhenInstanceDoesNotExist() {
|
||||||
deleteSyncLauncherInstance();
|
deleteSyncLauncherInstance();
|
||||||
startOnRunTaskAndVerify(BackgroundSyncLauncher.TASK_TAG, true, false, false);
|
startOnRunTaskAndVerify(BackgroundSyncLauncher.TASK_TAG, true, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@Feature({"NTPSnippets"})
|
@Feature({"NTPSnippets"})
|
||||||
public void testNTPSnippetsNoLaunchBrowserWhenInstanceExists() {
|
public void testNTPSnippetsFetchWifiChargingNoLaunchBrowserWhenInstanceExists() {
|
||||||
startOnRunTaskAndVerify(SnippetsLauncher.TASK_TAG_WIFI_CHARGING, false, false, true);
|
startOnRunTaskAndVerify(SnippetsLauncher.TASK_TAG_WIFI_CHARGING, false, false, true, false);
|
||||||
startOnRunTaskAndVerify(SnippetsLauncher.TASK_TAG_WIFI, false, false, true);
|
|
||||||
startOnRunTaskAndVerify(SnippetsLauncher.TASK_TAG_FALLBACK, false, false, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@Feature({"NTPSnippets"})
|
@Feature({"NTPSnippets"})
|
||||||
public void testNTPSnippetsLaunchBrowserWhenInstanceDoesNotExist() {
|
public void testNTPSnippetsFetchWifiNoLaunchBrowserWhenInstanceExists() {
|
||||||
|
startOnRunTaskAndVerify(SnippetsLauncher.TASK_TAG_WIFI, false, false, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
@Feature({"NTPSnippets"})
|
||||||
|
public void testNTPSnippetsFetchFallbackNoLaunchBrowserWhenInstanceExists() {
|
||||||
|
startOnRunTaskAndVerify(SnippetsLauncher.TASK_TAG_FALLBACK, false, false, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
@Feature({"NTPSnippets"})
|
||||||
|
public void testNTPSnippetsRescheduleNoLaunchBrowserWhenInstanceExists() {
|
||||||
|
startOnRunTaskAndVerify(SnippetsLauncher.TASK_TAG_RESCHEDULE, false, false, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
@Feature({"NTPSnippets"})
|
||||||
|
public void testNTPSnippetsFetchWifiChargingLaunchBrowserWhenInstanceDoesNotExist() {
|
||||||
deleteSnippetsLauncherInstance();
|
deleteSnippetsLauncherInstance();
|
||||||
startOnRunTaskAndVerify(SnippetsLauncher.TASK_TAG_WIFI_CHARGING, true, false, true);
|
startOnRunTaskAndVerify(SnippetsLauncher.TASK_TAG_WIFI_CHARGING, true, false, true, false);
|
||||||
startOnRunTaskAndVerify(SnippetsLauncher.TASK_TAG_WIFI, true, false, true);
|
}
|
||||||
startOnRunTaskAndVerify(SnippetsLauncher.TASK_TAG_FALLBACK, true, false, true);
|
|
||||||
|
@SmallTest
|
||||||
|
@Feature({"NTPSnippets"})
|
||||||
|
public void testNTPSnippetsFetchWifiLaunchBrowserWhenInstanceDoesNotExist() {
|
||||||
|
deleteSnippetsLauncherInstance();
|
||||||
|
startOnRunTaskAndVerify(SnippetsLauncher.TASK_TAG_WIFI, true, false, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
@Feature({"NTPSnippets"})
|
||||||
|
public void testNTPSnippetsFetchFallbackLaunchBrowserWhenInstanceDoesNotExist() {
|
||||||
|
deleteSnippetsLauncherInstance();
|
||||||
|
startOnRunTaskAndVerify(SnippetsLauncher.TASK_TAG_FALLBACK, true, false, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
@Feature({"NTPSnippets"})
|
||||||
|
public void testNTPSnippetsRescheduleLaunchBrowserWhenInstanceDoesNotExist() {
|
||||||
|
deleteSnippetsLauncherInstance();
|
||||||
|
startOnRunTaskAndVerify(SnippetsLauncher.TASK_TAG_RESCHEDULE, true, false, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@Feature({"Precache"})
|
@Feature({"Precache"})
|
||||||
public void testPrecacheNoLaunchBrowserWhenInstanceExists() {
|
public void testPrecacheNoLaunchBrowserWhenInstanceExists() {
|
||||||
startOnRunTaskAndVerify(PrecacheController.PERIODIC_TASK_TAG, false, false, false);
|
startOnRunTaskAndVerify(PrecacheController.PERIODIC_TASK_TAG, false, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@Feature({"Precache"})
|
@Feature({"Precache"})
|
||||||
public void testPrecacheLaunchBrowserWhenInstanceDoesNotExist() {
|
public void testPrecacheLaunchBrowserWhenInstanceDoesNotExist() {
|
||||||
mTaskService.deletePrecacheInstance();
|
mTaskService.deletePrecacheInstance();
|
||||||
startOnRunTaskAndVerify(PrecacheController.PERIODIC_TASK_TAG, true, true, false);
|
startOnRunTaskAndVerify(PrecacheController.PERIODIC_TASK_TAG, true, true, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -36,6 +36,14 @@ static void FetchSnippets(JNIEnv* env,
|
|||||||
NTPSnippetsServiceFactory::GetForProfile(profile)->FetchSnippets();
|
NTPSnippetsServiceFactory::GetForProfile(profile)->FetchSnippets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reschedules the fetching of snippets. Used to support different fetching
|
||||||
|
// intervals for different times of day.
|
||||||
|
static void RescheduleFetching(JNIEnv* env,
|
||||||
|
const JavaParamRef<jclass>& caller) {
|
||||||
|
Profile* profile = ProfileManager::GetLastUsedProfile();
|
||||||
|
NTPSnippetsServiceFactory::GetForProfile(profile)->RescheduleFetching();
|
||||||
|
}
|
||||||
|
|
||||||
NTPSnippetsBridge::NTPSnippetsBridge(JNIEnv* env,
|
NTPSnippetsBridge::NTPSnippetsBridge(JNIEnv* env,
|
||||||
const JavaParamRef<jobject>& j_profile)
|
const JavaParamRef<jobject>& j_profile)
|
||||||
: snippet_service_observer_(this) {
|
: snippet_service_observer_(this) {
|
||||||
|
@@ -30,13 +30,15 @@ bool NTPSnippetsLauncher::Register(JNIEnv* env) {
|
|||||||
|
|
||||||
bool NTPSnippetsLauncher::Schedule(base::TimeDelta period_wifi_charging,
|
bool NTPSnippetsLauncher::Schedule(base::TimeDelta period_wifi_charging,
|
||||||
base::TimeDelta period_wifi,
|
base::TimeDelta period_wifi,
|
||||||
base::TimeDelta period_fallback) {
|
base::TimeDelta period_fallback,
|
||||||
|
base::Time reschedule_time) {
|
||||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||||
|
|
||||||
JNIEnv* env = base::android::AttachCurrentThread();
|
JNIEnv* env = base::android::AttachCurrentThread();
|
||||||
return Java_SnippetsLauncher_schedule(
|
return Java_SnippetsLauncher_schedule(
|
||||||
env, java_launcher_.obj(), period_wifi_charging.InSeconds(),
|
env, java_launcher_.obj(), period_wifi_charging.InSeconds(),
|
||||||
period_wifi.InSeconds(), period_fallback.InSeconds());
|
period_wifi.InSeconds(), period_fallback.InSeconds(),
|
||||||
|
reschedule_time.ToJavaTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NTPSnippetsLauncher::Unschedule() {
|
bool NTPSnippetsLauncher::Unschedule() {
|
||||||
|
@@ -23,7 +23,8 @@ class NTPSnippetsLauncher : public ntp_snippets::NTPSnippetsScheduler {
|
|||||||
// ntp_snippets::NTPSnippetsScheduler implementation.
|
// ntp_snippets::NTPSnippetsScheduler implementation.
|
||||||
bool Schedule(base::TimeDelta period_wifi_charging,
|
bool Schedule(base::TimeDelta period_wifi_charging,
|
||||||
base::TimeDelta period_wifi,
|
base::TimeDelta period_wifi,
|
||||||
base::TimeDelta period_fallback) override;
|
base::TimeDelta period_fallback,
|
||||||
|
base::Time reschedule_time) override;
|
||||||
bool Unschedule() override;
|
bool Unschedule() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -14,13 +14,18 @@ namespace ntp_snippets {
|
|||||||
class NTPSnippetsScheduler {
|
class NTPSnippetsScheduler {
|
||||||
public:
|
public:
|
||||||
// Schedule periodic fetching of snippets, with different period depending on
|
// Schedule periodic fetching of snippets, with different period depending on
|
||||||
// network and charging state. The concrete implementation should call
|
// network and charging state, and also set up a delay after which the periods
|
||||||
// NTPSnippetsService::FetchSnippets once per period.
|
// may change. The concrete implementation should call
|
||||||
|
// NTPSnippetsService::FetchSnippets once per period, and
|
||||||
|
// NTPSnippetsService::RescheduleFetching at |reschedule_time|.
|
||||||
|
// Any of the values can be zero to indicate that the corresponding task
|
||||||
|
// should not be scheduled.
|
||||||
virtual bool Schedule(base::TimeDelta period_wifi_charging,
|
virtual bool Schedule(base::TimeDelta period_wifi_charging,
|
||||||
base::TimeDelta period_wifi,
|
base::TimeDelta period_wifi,
|
||||||
base::TimeDelta period_fallback) = 0;
|
base::TimeDelta period_fallback,
|
||||||
|
base::Time reschedule_time) = 0;
|
||||||
|
|
||||||
// Cancel the scheduled fetching task, if any.
|
// Cancel any scheduled tasks.
|
||||||
virtual bool Unschedule() = 0;
|
virtual bool Unschedule() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@@ -35,6 +35,11 @@ const int kFetchingIntervalWifiChargingSeconds = 30 * 60;
|
|||||||
const int kFetchingIntervalWifiSeconds = 2 * 60 * 60;
|
const int kFetchingIntervalWifiSeconds = 2 * 60 * 60;
|
||||||
const int kFetchingIntervalFallbackSeconds = 24 * 60 * 60;
|
const int kFetchingIntervalFallbackSeconds = 24 * 60 * 60;
|
||||||
|
|
||||||
|
// These define the times of day during which we will fetch via Wifi (without
|
||||||
|
// charging) - 6 AM to 10 PM.
|
||||||
|
const int kWifiFetchingHourMin = 6;
|
||||||
|
const int kWifiFetchingHourMax = 22;
|
||||||
|
|
||||||
const int kDefaultExpiryTimeMins = 24 * 60;
|
const int kDefaultExpiryTimeMins = 24 * 60;
|
||||||
|
|
||||||
base::TimeDelta GetFetchingInterval(const char* switch_name,
|
base::TimeDelta GetFetchingInterval(const char* switch_name,
|
||||||
@@ -57,9 +62,16 @@ base::TimeDelta GetFetchingIntervalWifiCharging() {
|
|||||||
kFetchingIntervalWifiChargingSeconds);
|
kFetchingIntervalWifiChargingSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
base::TimeDelta GetFetchingIntervalWifi() {
|
base::TimeDelta GetFetchingIntervalWifi(const base::Time& now) {
|
||||||
return GetFetchingInterval(switches::kFetchingIntervalWifiSeconds,
|
// Only fetch via Wifi (without charging) during the proper times of day.
|
||||||
kFetchingIntervalWifiSeconds);
|
base::Time::Exploded exploded;
|
||||||
|
now.LocalExplode(&exploded);
|
||||||
|
if (kWifiFetchingHourMin <= exploded.hour &&
|
||||||
|
exploded.hour < kWifiFetchingHourMax) {
|
||||||
|
return GetFetchingInterval(switches::kFetchingIntervalWifiSeconds,
|
||||||
|
kFetchingIntervalWifiSeconds);
|
||||||
|
}
|
||||||
|
return base::TimeDelta();
|
||||||
}
|
}
|
||||||
|
|
||||||
base::TimeDelta GetFetchingIntervalFallback() {
|
base::TimeDelta GetFetchingIntervalFallback() {
|
||||||
@@ -67,6 +79,31 @@ base::TimeDelta GetFetchingIntervalFallback() {
|
|||||||
kFetchingIntervalFallbackSeconds);
|
kFetchingIntervalFallbackSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base::Time GetRescheduleTime(const base::Time& now) {
|
||||||
|
base::Time::Exploded exploded;
|
||||||
|
now.LocalExplode(&exploded);
|
||||||
|
// The scheduling changes at both |kWifiFetchingHourMin| and
|
||||||
|
// |kWifiFetchingHourMax|. Find the time of the next one that we'll hit.
|
||||||
|
bool next_day = false;
|
||||||
|
if (exploded.hour < kWifiFetchingHourMin) {
|
||||||
|
exploded.hour = kWifiFetchingHourMin;
|
||||||
|
} else if (exploded.hour < kWifiFetchingHourMax) {
|
||||||
|
exploded.hour = kWifiFetchingHourMax;
|
||||||
|
} else {
|
||||||
|
next_day = true;
|
||||||
|
exploded.hour = kWifiFetchingHourMin;
|
||||||
|
}
|
||||||
|
// In any case, reschedule at the full hour.
|
||||||
|
exploded.minute = 0;
|
||||||
|
exploded.second = 0;
|
||||||
|
exploded.millisecond = 0;
|
||||||
|
base::Time reschedule = base::Time::FromLocalExploded(exploded);
|
||||||
|
if (next_day)
|
||||||
|
reschedule += base::TimeDelta::FromDays(1);
|
||||||
|
|
||||||
|
return reschedule;
|
||||||
|
}
|
||||||
|
|
||||||
// Extracts the hosts from |suggestions| and returns them in a set.
|
// Extracts the hosts from |suggestions| and returns them in a set.
|
||||||
std::set<std::string> GetSuggestionsHostsImpl(
|
std::set<std::string> GetSuggestionsHostsImpl(
|
||||||
const SuggestionsProfile& suggestions) {
|
const SuggestionsProfile& suggestions) {
|
||||||
@@ -124,7 +161,8 @@ NTPSnippetsService::NTPSnippetsService(
|
|||||||
NTPSnippetsScheduler* scheduler,
|
NTPSnippetsScheduler* scheduler,
|
||||||
scoped_ptr<NTPSnippetsFetcher> snippets_fetcher,
|
scoped_ptr<NTPSnippetsFetcher> snippets_fetcher,
|
||||||
const ParseJSONCallback& parse_json_callback)
|
const ParseJSONCallback& parse_json_callback)
|
||||||
: pref_service_(pref_service),
|
: enabled_(false),
|
||||||
|
pref_service_(pref_service),
|
||||||
suggestions_service_(suggestions_service),
|
suggestions_service_(suggestions_service),
|
||||||
file_task_runner_(file_task_runner),
|
file_task_runner_(file_task_runner),
|
||||||
application_language_code_(application_language_code),
|
application_language_code_(application_language_code),
|
||||||
@@ -146,7 +184,8 @@ void NTPSnippetsService::RegisterProfilePrefs(PrefRegistrySimple* registry) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NTPSnippetsService::Init(bool enabled) {
|
void NTPSnippetsService::Init(bool enabled) {
|
||||||
if (enabled) {
|
enabled_ = enabled;
|
||||||
|
if (enabled_) {
|
||||||
// |suggestions_service_| can be null in tests.
|
// |suggestions_service_| can be null in tests.
|
||||||
if (suggestions_service_) {
|
if (suggestions_service_) {
|
||||||
suggestions_service_subscription_ = suggestions_service_->AddCallback(
|
suggestions_service_subscription_ = suggestions_service_->AddCallback(
|
||||||
@@ -163,22 +202,13 @@ void NTPSnippetsService::Init(bool enabled) {
|
|||||||
FetchSnippets();
|
FetchSnippets();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The scheduler only exists on Android so far, it's null on other platforms.
|
RescheduleFetching();
|
||||||
if (!scheduler_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (enabled) {
|
|
||||||
scheduler_->Schedule(GetFetchingIntervalWifiCharging(),
|
|
||||||
GetFetchingIntervalWifi(),
|
|
||||||
GetFetchingIntervalFallback());
|
|
||||||
} else {
|
|
||||||
scheduler_->Unschedule();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NTPSnippetsService::Shutdown() {
|
void NTPSnippetsService::Shutdown() {
|
||||||
FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_,
|
FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_,
|
||||||
NTPSnippetsServiceShutdown());
|
NTPSnippetsServiceShutdown());
|
||||||
|
enabled_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NTPSnippetsService::FetchSnippets() {
|
void NTPSnippetsService::FetchSnippets() {
|
||||||
@@ -196,6 +226,21 @@ void NTPSnippetsService::FetchSnippetsFromHosts(
|
|||||||
snippets_fetcher_->FetchSnippets(hosts);
|
snippets_fetcher_->FetchSnippets(hosts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NTPSnippetsService::RescheduleFetching() {
|
||||||
|
// The scheduler only exists on Android so far, it's null on other platforms.
|
||||||
|
if (!scheduler_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (enabled_) {
|
||||||
|
base::Time now = base::Time::Now();
|
||||||
|
scheduler_->Schedule(
|
||||||
|
GetFetchingIntervalWifiCharging(), GetFetchingIntervalWifi(now),
|
||||||
|
GetFetchingIntervalFallback(), GetRescheduleTime(now));
|
||||||
|
} else {
|
||||||
|
scheduler_->Unschedule();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NTPSnippetsService::ClearSnippets() {
|
void NTPSnippetsService::ClearSnippets() {
|
||||||
snippets_.clear();
|
snippets_.clear();
|
||||||
|
|
||||||
|
@@ -79,6 +79,10 @@ class NTPSnippetsService : public KeyedService {
|
|||||||
// suggestions from the suggestion service) and adds them to the current ones.
|
// suggestions from the suggestion service) and adds them to the current ones.
|
||||||
void FetchSnippetsFromHosts(const std::set<std::string>& hosts);
|
void FetchSnippetsFromHosts(const std::set<std::string>& hosts);
|
||||||
|
|
||||||
|
// (Re)schedules the periodic fetching of snippets. This is necessary because
|
||||||
|
// the schedule depends on the time of day
|
||||||
|
void RescheduleFetching();
|
||||||
|
|
||||||
// Deletes all currently stored snippets.
|
// Deletes all currently stored snippets.
|
||||||
void ClearSnippets();
|
void ClearSnippets();
|
||||||
|
|
||||||
@@ -148,6 +152,8 @@ class NTPSnippetsService : public KeyedService {
|
|||||||
|
|
||||||
void RemoveExpiredSnippets();
|
void RemoveExpiredSnippets();
|
||||||
|
|
||||||
|
bool enabled_;
|
||||||
|
|
||||||
PrefService* pref_service_;
|
PrefService* pref_service_;
|
||||||
|
|
||||||
suggestions::SuggestionsService* suggestions_service_;
|
suggestions::SuggestionsService* suggestions_service_;
|
||||||
|
Reference in New Issue
Block a user