Commit b7b13868 authored by Wenzhao Zang's avatar Wenzhao Zang Committed by Commit Bot

cros: Fetch daily refresh image from Backdrop service

1) The new wallpaper picker relies on the Backdrop server to select
   surprise me images, instead of selecting random images by ourseleves
   (the back-end was implemented by a prior CL).

2) The surprise me images are per-category, ie. each wallpaper category
   has a "daily refresh slider". At most one slider may be active at
   a time. Toggling one slider to active should deactivate others.

3) Use "daily refresh" instead of "surprise me" in the code to
   distinguish from the old picker. Although it's possible to share
   code path with the old picker, generally avoid it for clarity.

Test steps include:
1) Toggle daily refresh between enabled/disabled, during
   tablet/clamshell mode, and among different categories.
2) Enable surprise me on the old picker, then add switch
   --new-wallpaper-picker, and see the migration.
3) See the sync is working for two devices with the same account id.

Bug: 834998, 810169, 834994, 837338
Change-Id: I369ce57ac4bd07e91da31bb2971b6970501f9c3a
Reviewed-on: https://chromium-review.googlesource.com/1093742
Commit-Queue: Wenzhao (Colin) Zang <wzang@chromium.org>
Reviewed-by: default avatarXiaoqian Dai <xdai@chromium.org>
Cr-Commit-Position: refs/heads/master@{#568732}
parent 26d1c8e8
...@@ -623,6 +623,10 @@ body.v2 { ...@@ -623,6 +623,10 @@ body.v2 {
color: rgb(32, 33, 36); color: rgb(32, 33, 36);
} }
.v2.daily-wallpaper .top-header-contents #wallpaper-description {
max-width: 226px;
}
.v2 .top-header-contents .more-options { .v2 .top-header-contents .more-options {
display: flex; display: flex;
position: absolute; position: absolute;
...@@ -635,6 +639,7 @@ html[dir='rtl'] .v2 .top-header-contents .more-options { ...@@ -635,6 +639,7 @@ html[dir='rtl'] .v2 .top-header-contents .more-options {
} }
.v2 .top-header-contents .more-options > div { .v2 .top-header-contents .more-options > div {
background-color: #fff;
border: 0.5px solid; border: 0.5px solid;
border-color: rgba(128, 134, 139, 0.6); border-color: rgba(128, 134, 139, 0.6);
border-radius: 16px; border-radius: 16px;
...@@ -699,8 +704,17 @@ html[dir='rtl'] .v2 .top-header-contents .more-options { ...@@ -699,8 +704,17 @@ html[dir='rtl'] .v2 .top-header-contents .more-options {
-webkit-margin-start: 96px; -webkit-margin-start: 96px;
} }
.v2.daily-wallpaper .top-header-contents #confirm-preview-wallpaper {
-webkit-margin-start: 8px;
}
.v2 .top-header-contents #refresh-wallpaper {
-webkit-margin-start: 16px;
}
.v2.preview-mode.custom-wallpaper .more-options .custom-option, .v2.preview-mode.custom-wallpaper .more-options .custom-option,
.v2.preview-mode:not(.custom-wallpaper) .more-options :not(.custom-option) { .v2.preview-mode.daily-wallpaper .more-options .daily-option,
.v2.preview-mode:not(.custom-wallpaper):not(.daily-option) .more-options :not(.custom-option):not(.daily-option) {
display: flex; display: flex;
} }
......
...@@ -25,7 +25,8 @@ ...@@ -25,7 +25,8 @@
AccessSyncWallpaperInfoKey: 'wallpaper-sync-info-key', AccessSyncWallpaperInfoKey: 'wallpaper-sync-info-key',
/** /**
* Key to access last changed date of a surprise wallpaper in * Key to access last changed date of a surprise me wallpaper (on the old
* picker) or a daily refresh wallpaper (on the new picker) in
* chrome.storage.local or chrome.storage.sync. * chrome.storage.local or chrome.storage.sync.
*/ */
AccessLastSurpriseWallpaperChangedDate: 'wallpaper-last-changed-date-key', AccessLastSurpriseWallpaperChangedDate: 'wallpaper-last-changed-date-key',
...@@ -42,6 +43,18 @@ ...@@ -42,6 +43,18 @@
*/ */
AccessSyncSurpriseMeEnabledKey: 'sync-surprise-me-enabled-key', AccessSyncSurpriseMeEnabledKey: 'sync-surprise-me-enabled-key',
/**
* Key to access the info related to daily refresh feature (on the new
* wallpaper picker) in chrome.storage.local.
*/
AccessLocalDailyRefreshInfoKey: 'daily-refresh-info-key',
/**
* Key to access the info related to daily refresh feature (on the new
* wallpaper picker) in chrome.storage.sync.
*/
AccessSyncDailyRefreshInfoKey: 'sync-daily-refresh-info-key',
/** /**
* URL to get latest wallpaper RSS feed. * URL to get latest wallpaper RSS feed.
*/ */
......
...@@ -207,45 +207,62 @@ SurpriseWallpaper.prototype.setRandomWallpaperFromManifest_ = function( ...@@ -207,45 +207,62 @@ SurpriseWallpaper.prototype.setRandomWallpaperFromManifest_ = function(
*/ */
SurpriseWallpaper.prototype.setRandomWallpaperFromServer_ = function( SurpriseWallpaper.prototype.setRandomWallpaperFromServer_ = function(
onSuccess, suffix) { onSuccess, suffix) {
// The first step is to get the list of wallpaper collections (ie. categories) var onDailyRefreshInfoReturned = dailyRefreshInfo => {
// and randomly select one. var setRandomWallpaperFromServerImpl = dailyRefreshInfo => {
chrome.wallpaperPrivate.getCollectionsInfo(collectionsInfo => { chrome.wallpaperPrivate.getSurpriseMeImage(
if (chrome.runtime.lastError) { dailyRefreshInfo.collectionId, dailyRefreshInfo.resumeToken,
this.retryLater_(); (imageInfo, nextResumeToken) => {
return; if (chrome.runtime.lastError) {
} this.retryLater_();
if (collectionsInfo.length == 0) { return;
// Although the fetch succeeds, it's theoretically possible that the }
// collection list is empty, in this case do nothing. dailyRefreshInfo.resumeToken = nextResumeToken;
WallpaperUtil.saveDailyRefreshInfo(dailyRefreshInfo);
var wallpaperUrl = imageInfo['imageUrl'] + suffix;
var layout = Constants.WallpaperThumbnailDefaultLayout;
WallpaperUtil.setOnlineWallpaperWithoutPreview(
wallpaperUrl, layout,
onSuccess.bind(null, wallpaperUrl, layout),
this.retryLater_.bind(this));
});
};
if (dailyRefreshInfo) {
if (dailyRefreshInfo.enabled) {
setRandomWallpaperFromServerImpl(dailyRefreshInfo);
} else {
console.error(
'Daily refresh is disabled when the alarm goes off. ' +
'This should never happen!');
}
return; return;
} }
var randomCollectionIndex = // Migration: we reach here if the old picker set an alarm and by the time
Math.floor(Math.random() * collectionsInfo.length); // the alarm goes off, the new picker is already in use. We should ensure
var collectionId = collectionsInfo[randomCollectionIndex]['collectionId']; // the user transitions to the daily refresh feature.
// The second step is to get the list of wallpapers that belong to the chrome.wallpaperPrivate.getCollectionsInfo(collectionsInfo => {
// particular collection, and randomly select one.
chrome.wallpaperPrivate.getImagesInfo(collectionId, imagesInfo => {
if (chrome.runtime.lastError) { if (chrome.runtime.lastError) {
this.retryLater_(); this.retryLater_();
return; return;
} }
if (imagesInfo.length == 0) { if (collectionsInfo.length == 0) {
// Although the fetch succeeds, it's theoretically possible that the // Although the fetch succeeds, it's theoretically possible that the
// image list is empty, in this case do nothing. // collection list is empty, in this case do nothing.
// TODO(crbug.com/800945): Consider fetching another collection.
return; return;
} }
var randomImageIndex = Math.floor(Math.random() * imagesInfo.length); dailyRefreshInfo = {
var wallpaperUrl = imagesInfo[randomImageIndex]['imageUrl'] + suffix; enabled: true,
// The backend service doesn't specify the desired layout. Use the default // Use the first collection (an arbitrary choice).
// layout here. collectionId: collectionsInfo[0]['collectionId'],
var layout = Constants.WallpaperThumbnailDefaultLayout; resumeToken: null
WallpaperUtil.setOnlineWallpaperWithoutPreview( };
wallpaperUrl, layout, onSuccess.bind(null, wallpaperUrl, layout), setRandomWallpaperFromServerImpl(dailyRefreshInfo);
this.retryLater_.bind(this));
}); });
}); };
WallpaperUtil.getDailyRefreshInfo(onDailyRefreshInfoReturned.bind(null));
}; };
/** /**
...@@ -401,6 +418,30 @@ chrome.syncFileSystem.onFileStatusChanged.addListener(function(detail) { ...@@ -401,6 +418,30 @@ chrome.syncFileSystem.onFileStatusChanged.addListener(function(detail) {
chrome.storage.onChanged.addListener(function(changes, namespace) { chrome.storage.onChanged.addListener(function(changes, namespace) {
WallpaperUtil.enabledSyncThemesCallback(function(syncEnabled) { WallpaperUtil.enabledSyncThemesCallback(function(syncEnabled) {
// Daily refresh feature is on the new wallpaper picker only.
var updateDailyRefreshStates = key => {
if (!changes[key])
return;
var oldDailyRefreshInfo = JSON.parse(changes[key].oldValue);
var newDailyRefreshInfo = JSON.parse(changes[key].newValue);
// The resume token is expected to change after a new daily refresh
// wallpaper is set. Ignore it if it's the only change.
if (oldDailyRefreshInfo.enabled === newDailyRefreshInfo.enabled &&
oldDailyRefreshInfo.collectionId ===
newDailyRefreshInfo.collectionId) {
return;
}
// Although the old and new values may both have enabled == true, they can
// have different collection ids, so the old alarm should always be
// cleared.
chrome.alarms.clearAll();
if (newDailyRefreshInfo.enabled)
SurpriseWallpaper.getInstance().next();
};
updateDailyRefreshStates(
syncEnabled ? Constants.AccessSyncDailyRefreshInfoKey :
Constants.AccessLocalDailyRefreshInfoKey);
if (syncEnabled) { if (syncEnabled) {
// If sync theme is enabled, use values from chrome.storage.sync to sync // If sync theme is enabled, use values from chrome.storage.sync to sync
// wallpaper changes. // wallpaper changes.
...@@ -462,12 +503,14 @@ chrome.storage.onChanged.addListener(function(changes, namespace) { ...@@ -462,12 +503,14 @@ chrome.storage.onChanged.addListener(function(changes, namespace) {
wpDocument.querySelector('.check').style.visibility = wpDocument.querySelector('.check').style.visibility =
'visible'; 'visible';
} }
wpDocument.querySelector('#categories-list').disabled = enable;
chrome.commandLinePrivate.hasSwitch( chrome.commandLinePrivate.hasSwitch(
'new-wallpaper-picker', useNewWallpaperPicker => { 'new-wallpaper-picker', useNewWallpaperPicker => {
if (!useNewWallpaperPicker) if (!useNewWallpaperPicker) {
wpDocument.querySelector('#wallpaper-grid').disabled = wpDocument.querySelector('#wallpaper-grid').disabled =
enable; enable;
wpDocument.querySelector('#categories-list').disabled =
enable;
}
}); });
}); });
} }
......
...@@ -500,3 +500,71 @@ WallpaperUtil.testSendMessage = function(message) { ...@@ -500,3 +500,71 @@ WallpaperUtil.testSendMessage = function(message) {
if (test) if (test)
test.sendMessage(message); test.sendMessage(message);
}; };
/**
* Gets the daily refresh info from sync storage, or local storage if the former
* is not available.
* @param {function} callback A callback that takes the value of the info, or
* null if the value is invalid.
*/
WallpaperUtil.getDailyRefreshInfo = function(callback) {
WallpaperUtil.enabledSyncThemesCallback(syncEnabled => {
var parseInfo = dailyRefreshInfoJson => {
if (!dailyRefreshInfoJson) {
callback(null);
return;
}
var dailyRefreshInfo = JSON.parse(dailyRefreshInfoJson);
if (!dailyRefreshInfo.hasOwnProperty('enabled') ||
!dailyRefreshInfo.hasOwnProperty('collectionId') ||
!dailyRefreshInfo.hasOwnProperty('resumeToken')) {
callback(null);
return;
}
callback(dailyRefreshInfo);
};
if (syncEnabled) {
Constants.WallpaperSyncStorage.get(
Constants.AccessSyncDailyRefreshInfoKey, items => {
var dailyRefreshInfoJson =
items[Constants.AccessSyncDailyRefreshInfoKey];
if (dailyRefreshInfoJson) {
parseInfo(dailyRefreshInfoJson);
} else {
Constants.WallpaperLocalStorage.get(
Constants.AccessLocalDailyRefreshInfoKey, items => {
dailyRefreshInfoJson =
items[Constants.AccessLocalDailyRefreshInfoKey];
parseInfo(dailyRefreshInfoJson);
if (dailyRefreshInfoJson) {
WallpaperUtil.saveToSyncStorage(
Constants.AccessSyncDailyRefreshInfoKey,
dailyRefreshInfoJson);
}
});
}
});
} else {
Constants.WallpaperLocalStorage.get(
Constants.AccessLocalDailyRefreshInfoKey, items => {
parseInfo(items[Constants.AccessLocalDailyRefreshInfoKey]);
});
}
});
};
/**
* Saves the daily refresh info to local and sync storage.
* @param {Object} dailyRefreshInfo The daily refresh info.
*/
WallpaperUtil.saveDailyRefreshInfo = function(dailyRefreshInfo) {
var dailyRefreshInfoJson = JSON.stringify(dailyRefreshInfo);
WallpaperUtil.saveToLocalStorage(
Constants.AccessLocalDailyRefreshInfoKey, dailyRefreshInfoJson,
null /*opt_callback=*/);
WallpaperUtil.saveToSyncStorage(
Constants.AccessSyncDailyRefreshInfoKey, dailyRefreshInfoJson,
null /*opt_callback=*/);
};
...@@ -387,6 +387,15 @@ cr.define('wallpapers', function() { ...@@ -387,6 +387,15 @@ cr.define('wallpapers', function() {
{}; {};
}, },
/**
* The id of the collection that the wallpapers belong to, assuming all the
* wallpapers have the same id (enfored by the source of the data model).
* @type {string}
*/
get collectionId() {
return this.dataModel.item(this.dataModel.length - 1).collectionId;
},
/** /**
* A unique ID that assigned to each set dataModel operation. Note that this * A unique ID that assigned to each set dataModel operation. Note that this
* id wont increase if the new dataModel is null or empty. * id wont increase if the new dataModel is null or empty.
...@@ -697,11 +706,9 @@ cr.define('wallpapers', function() { ...@@ -697,11 +706,9 @@ cr.define('wallpapers', function() {
if (!this.dailyRefreshItem.querySelector('.daily-refresh-banner')) { if (!this.dailyRefreshItem.querySelector('.daily-refresh-banner')) {
var dailyRefreshBanner = document.querySelector('.daily-refresh-banner') var dailyRefreshBanner = document.querySelector('.daily-refresh-banner')
.cloneNode(true /*deep=*/); .cloneNode(true /*deep=*/);
dailyRefreshBanner.querySelector('.daily-refresh-slider') wallpaperManager.decorateDailyRefreshSlider(
.addEventListener( this.collectionId,
'click', dailyRefreshBanner.querySelector('.daily-refresh-slider'));
WallpaperManager.prototype.toggleSurpriseMe.bind(
wallpaperManager));
this.dailyRefreshItem.appendChild(dailyRefreshBanner); this.dailyRefreshItem.appendChild(dailyRefreshBanner);
} }
......
...@@ -181,6 +181,8 @@ found in the LICENSE file. ...@@ -181,6 +181,8 @@ found in the LICENSE file.
<div class="icon"></div> <div class="icon"></div>
<div class="text" i18n-content="centerCroppedLayout"></div> <div class="text" i18n-content="centerCroppedLayout"></div>
</div> </div>
<div id="refresh-wallpaper" class="daily-option"
i18n-content="refreshLabel"></div>
<div id="confirm-preview-wallpaper" class="preview-option" <div id="confirm-preview-wallpaper" class="preview-option"
i18n-content="confirmPreviewLabel"></div> i18n-content="confirmPreviewLabel"></div>
</div> </div>
......
...@@ -286,6 +286,10 @@ var chrome = { ...@@ -286,6 +286,10 @@ var chrome = {
}, },
getImagesInfo: function(collectionId, callback) { getImagesInfo: function(collectionId, callback) {
callback([{imageUrl: TestConstants.wallpaperUrl}]); callback([{imageUrl: TestConstants.wallpaperUrl}]);
},
getSurpriseMeImage: function(collectionId, resumeToken, callback) {
callback(
{imageUrl: TestConstants.wallpaperUrl}, null /*nextResumeToken=*/);
} }
}, },
runtime: {lastError: null}, runtime: {lastError: null},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment