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

Unified Diff: chrome/browser/resources/google_now/background.js

Issue 248473003: Attempt Manager Refactor and Opt-In Pipeline Refactor (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Quick Comment Fix Created 6 years, 7 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/browser/resources/google_now/background.js
diff --git a/chrome/browser/resources/google_now/background.js b/chrome/browser/resources/google_now/background.js
index d2d3f3b83be0ec77b6e048be57e87de770dddcb9..72255cd0691a4367e248046232587a269fbff5b9 100644
--- a/chrome/browser/resources/google_now/background.js
+++ b/chrome/browser/resources/google_now/background.js
@@ -54,14 +54,14 @@ var MAXIMUM_POLLING_PERIOD_SECONDS = 60 * 60; // 1 hour
* Initial period for polling for Google Now optin notification after push
* messaging indicates Google Now is enabled.
*/
-var INITIAL_OPTIN_POLLING_PERIOD_SECONDS = 60; // 1 minute
+var INITIAL_OPTIN_RECHECK_PERIOD_SECONDS = 60; // 1 minute
/**
* Maximum period for polling for Google Now optin notification after push
* messaging indicates Google Now is enabled. It is expected that the alarm
* will be stopped after this.
*/
-var MAXIMUM_OPTIN_POLLING_PERIOD_SECONDS = 16 * 60; // 16 minutes
+var MAXIMUM_OPTIN_RECHECK_PERIOD_SECONDS = 16 * 60; // 16 minutes
/**
* Initial period for retrying the server request for dismissing cards.
@@ -205,6 +205,7 @@ wrapper.instrumentChromeApiFunction(
'notifications.onShowSettings.addListener', 0);
wrapper.instrumentChromeApiFunction('permissions.contains', 1);
wrapper.instrumentChromeApiFunction('pushMessaging.onMessage.addListener', 0);
+wrapper.instrumentChromeApiFunction('storage.onChanged.addListener', 0);
wrapper.instrumentChromeApiFunction('runtime.onInstalled.addListener', 0);
wrapper.instrumentChromeApiFunction('runtime.onStartup.addListener', 0);
wrapper.instrumentChromeApiFunction('tabs.create', 1);
@@ -214,11 +215,16 @@ var updateCardsAttempts = buildAttemptManager(
requestCards,
INITIAL_POLLING_PERIOD_SECONDS,
MAXIMUM_POLLING_PERIOD_SECONDS);
-var optInCheckAttempts = buildAttemptManager(
+var optInPollAttempts = buildAttemptManager(
'optin',
- pollOptedIn,
- INITIAL_OPTIN_POLLING_PERIOD_SECONDS,
- MAXIMUM_OPTIN_POLLING_PERIOD_SECONDS);
+ pollOptedInNoImmediateRecheck,
+ INITIAL_POLLING_PERIOD_SECONDS,
+ MAXIMUM_POLLING_PERIOD_SECONDS);
+var optInRecheckAttempts = buildAttemptManager(
+ 'optin-recheck',
+ pollOptedInWithRecheck,
+ INITIAL_OPTIN_RECHECK_PERIOD_SECONDS,
+ MAXIMUM_OPTIN_RECHECK_PERIOD_SECONDS);
var dismissalAttempts = buildAttemptManager(
'dismiss',
retryPendingDismissals,
@@ -425,39 +431,52 @@ function combineGroup(combinedCards, storedGroup) {
}
/**
- * Schedules next cards poll.
+ * Calculates the soonest poll time from a map of groups as an absolute time.
* @param {Object.<string, StoredNotificationGroup>} groups Map from group name
* to group information.
- * @param {boolean} isOptedIn True if the user is opted in to Google Now.
+ * @return {number} The next poll time based off of the groups.
*/
-function scheduleNextPoll(groups, isOptedIn) {
- if (isOptedIn) {
- var nextPollTime = null;
-
- for (var groupName in groups) {
- var group = groups[groupName];
- if (group.nextPollTime !== undefined) {
- nextPollTime = nextPollTime == null ?
- group.nextPollTime : Math.min(group.nextPollTime, nextPollTime);
- }
+function calculateNextPollTimeMilliseconds(groups) {
+ var nextPollTime = null;
+
+ for (var groupName in groups) {
+ var group = groups[groupName];
+ if (group.nextPollTime !== undefined) {
+ nextPollTime = nextPollTime == null ?
+ group.nextPollTime : Math.min(group.nextPollTime, nextPollTime);
}
+ }
- // At least one of the groups must have nextPollTime.
- verify(nextPollTime != null, 'scheduleNextPoll: nextPollTime is null');
+ // At least one of the groups must have nextPollTime.
+ verify(nextPollTime != null, 'calculateNextPollTime: nextPollTime is null');
+ return nextPollTime;
+}
- var nextPollDelaySeconds = Math.max(
- (nextPollTime - Date.now()) / MS_IN_SECOND,
- MINIMUM_POLLING_PERIOD_SECONDS);
- updateCardsAttempts.start(nextPollDelaySeconds);
- } else {
- instrumented.metricsPrivate.getVariationParams(
- 'GoogleNow', function(params) {
- var optinPollPeriodSeconds =
- parseInt(params && params.optinPollPeriodSeconds, 10) ||
- DEFAULT_OPTIN_CHECK_PERIOD_SECONDS;
- updateCardsAttempts.start(optinPollPeriodSeconds);
- });
- }
+/**
+ * Schedules next cards poll.
+ * @param {Object.<string, StoredNotificationGroup>} groups Map from group name
+ * to group information.
+ */
+function scheduleNextCardsPoll(groups) {
+ var nextPollTimeMs = calculateNextPollTimeMilliseconds(groups);
+
+ var nextPollDelaySeconds = Math.max(
+ (nextPollTimeMs - Date.now()) / MS_IN_SECOND,
+ MINIMUM_POLLING_PERIOD_SECONDS);
+ updateCardsAttempts.start(nextPollDelaySeconds);
+}
+
+/**
+ * Schedules the next opt-in check poll.
+ */
+function scheduleOptInCheckPoll() {
+ instrumented.metricsPrivate.getVariationParams(
+ 'GoogleNow', function(params) {
+ var optinPollPeriodSeconds =
+ parseInt(params && params.optinPollPeriodSeconds, 10) ||
+ DEFAULT_OPTIN_CHECK_PERIOD_SECONDS;
+ optInPollAttempts.start(optinPollPeriodSeconds);
+ });
}
/**
@@ -488,13 +507,6 @@ function processServerResponse(response) {
if (response.googleNowDisabled) {
chrome.storage.local.set({googleNowEnabled: false});
- // TODO(robliao): Remove the line below once the server stops sending groups
- // with 'googleNowDisabled' responses.
- response.groups = {};
- // Google Now was enabled; now it's disabled. This is a state change.
- onStateChange();
- // Start the Google Now Disabled polling period.
- scheduleNextPoll({}, false);
// Stop processing now. The state change will clear the cards.
return Promise.reject();
}
@@ -573,7 +585,7 @@ function processServerResponse(response) {
updatedGroups[groupName] = storedGroup;
}
- scheduleNextPoll(updatedGroups, !response.googleNowDisabled);
+ scheduleNextCardsPoll(updatedGroups);
return {
updatedGroups: updatedGroups,
recentDismissals: updatedRecentDismissals
@@ -638,10 +650,27 @@ function requestNotificationGroupsFromServer(groupNames) {
}
/**
+ * Performs an opt-in poll without an immediate recheck.
+ * If the response is not opted-in, schedule an opt-in check poll.
+ */
+function pollOptedInNoImmediateRecheck() {
+ requestAndUpdateOptedIn()
+ .then(function(optedIn) {
+ if (!optedIn) {
+ // Request a repoll if we're not opted in.
+ return Promise.reject();
+ }
+ })
+ .catch(function() {
+ scheduleOptInCheckPoll();
+ });
+}
+
+/**
* Requests the account opted-in state from the server and updates any
* state as necessary.
* @return {Promise} A promise to request and update the opted-in state.
- * The promise resolves if the opt-in state is true.
+ * The promise resolves with the opt-in state.
*/
function requestAndUpdateOptedIn() {
console.log('requestOptedIn from ' + NOTIFICATION_CARDS_URL);
@@ -654,15 +683,8 @@ function requestAndUpdateOptedIn() {
return parsedResponse.value;
}
}).then(function(optedIn) {
- if (optedIn) {
- chrome.storage.local.set({googleNowEnabled: true});
- // Google Now was disabled, now it's enabled. This is a state change.
- onStateChange();
- return Promise.resolve();
- } else {
- scheduleNextPoll({}, false);
- return Promise.reject();
- }
+ chrome.storage.local.set({googleNowEnabled: optedIn});
+ return optedIn;
});
}
@@ -695,12 +717,7 @@ function getGroupsToRequest() {
*/
function requestNotificationCards() {
console.log('requestNotificationCards');
-
- return isGoogleNowEnabled()
- .then(function(googleNowEnabled) {
- return googleNowEnabled ? Promise.resolve() : requestAndUpdateOptedIn();
- })
- .then(getGroupsToRequest)
+ return getGroupsToRequest()
.then(requestNotificationGroupsFromServer)
.then(processServerResponse)
.then(function(processedResponse) {
@@ -731,10 +748,10 @@ function requestCards() {
console.log('requestCards-task-begin');
updateCardsAttempts.isRunning(function(running) {
if (running) {
- updateCardsAttempts.planForNext(function() {
- // The cards are requested only if there are no unsent dismissals.
- processPendingDismissals().then(requestNotificationCards);
- });
+ // The cards are requested only if there are no unsent dismissals.
+ processPendingDismissals()
+ .then(requestNotificationCards)
+ .catch(updateCardsAttempts.scheduleRetry);
}
});
});
@@ -851,9 +868,7 @@ function processPendingDismissals() {
*/
function retryPendingDismissals() {
tasks.add(RETRY_DISMISS_TASK_NAME, function() {
- dismissalAttempts.planForNext(function() {
- processPendingDismissals();
- });
+ processPendingDismissals().catch(dismissalAttempts.scheduleRetry);
});
}
@@ -1006,6 +1021,28 @@ function setShouldPollCards(shouldPollCardsRequest) {
}
/**
+ * Starts or stops the optin check.
+ * @param {boolean} shouldPollOptInStatus true to start and false to stop
+ * polling the optin status.
+ */
+function setShouldPollOptInStatus(shouldPollOptInStatus) {
+ optInPollAttempts.isRunning(function(currentValue) {
+ if (shouldPollOptInStatus != currentValue) {
+ console.log(
+ 'Action Taken setShouldPollOptInStatus=' + shouldPollOptInStatus);
+ if (shouldPollOptInStatus) {
+ pollOptedInNoImmediateRecheck();
+ } else {
+ optInPollAttempts.stop();
+ }
+ } else {
+ console.log(
+ 'Action Ignored setShouldPollOptInStatus=' + shouldPollOptInStatus);
+ }
+ });
+}
+
+/**
* Enables or disables the Google Now background permission.
* @param {boolean} backgroundEnable true to run in the background.
* false to not run in the background.
@@ -1066,13 +1103,13 @@ function updateRunningState(
'googleNowEnabled=' + googleNowEnabled);
var shouldPollCards = false;
+ var shouldPollOptInStatus = false;
var shouldSetBackground = false;
- var shouldClearCards = true;
if (signedIn && notificationEnabled) {
- shouldClearCards = !googleNowEnabled;
+ shouldPollCards = googleNowEnabled;
+ shouldPollOptInStatus = !googleNowEnabled;
shouldSetBackground = canEnableBackground && googleNowEnabled;
- shouldPollCards = true;
} else {
recordEvent(GoogleNowEvent.STOPPED);
}
@@ -1082,11 +1119,12 @@ function updateRunningState(
console.log(
'Requested Actions shouldSetBackground=' + shouldSetBackground + ' ' +
'setShouldPollCards=' + shouldPollCards + ' ' +
- 'shouldClearCards=' + shouldClearCards);
+ 'shouldPollOptInStatus=' + shouldPollOptInStatus);
setBackgroundEnable(shouldSetBackground);
setShouldPollCards(shouldPollCards);
- if (shouldClearCards) {
+ setShouldPollOptInStatus(shouldPollOptInStatus);
+ if (!shouldPollCards) {
removeAllCards();
}
}
@@ -1152,30 +1190,35 @@ function isGoogleNowEnabled() {
* Sometimes we get the response to the opted in result too soon during
* push messaging. We'll recheck the optin state a few times before giving up.
*/
-function pollOptedIn() {
+function pollOptedInWithRecheck() {
/**
* Cleans up any state used to recheck the opt-in poll.
*/
function clearPollingState() {
localStorage.removeItem('optedInCheckCount');
- optInCheckAttempts.stop();
+ optInRecheckAttempts.stop();
}
if (localStorage.optedInCheckCount === undefined) {
localStorage.optedInCheckCount = 0;
- optInCheckAttempts.start();
+ optInRecheckAttempts.start();
}
console.log(new Date() +
' checkOptedIn Attempt ' + localStorage.optedInCheckCount);
- requestAndUpdateOptedIn().then(function() {
- clearPollingState();
- requestCards();
+ requestAndUpdateOptedIn().then(function(optedIn) {
+ if (optedIn) {
+ clearPollingState();
+ return Promise.resolve();
+ } else {
+ // If we're not opted in, reject to retry.
+ return Promise.reject();
+ }
}).catch(function() {
if (localStorage.optedInCheckCount < 5) {
localStorage.optedInCheckCount++;
- optInCheckAttempts.planForNext(function() {});
+ optInRecheckAttempts.scheduleRetry();
} else {
clearPollingState();
}
@@ -1259,6 +1302,15 @@ instrumented.notifications.onShowSettings.addListener(function() {
openUrl(SETTINGS_URL);
});
+// Handles state change notifications for the Google Now enabled bit.
+instrumented.storage.onChanged.addListener(function(changes, areaName) {
+ if (areaName === 'local') {
+ if ('googleNowEnabled' in changes) {
+ onStateChange();
+ }
+ }
+});
+
instrumented.pushMessaging.onMessage.addListener(function(message) {
// message.payload will be '' when the extension first starts.
// Each time after signing in, we'll get latest payload for all channels.
@@ -1288,7 +1340,7 @@ instrumented.pushMessaging.onMessage.addListener(function(message) {
notificationGroups: items.notificationGroups
});
- pollOptedIn();
+ pollOptedInWithRecheck();
}
});
});

Powered by Google App Engine
This is Rietveld 408576698