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

Unified Diff: chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc

Issue 2572793003: [Chrome OS] Implement the device wallpaper policy. (Closed)
Patch Set: Rebase. Created 4 years 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
« no previous file with comments | « chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h ('k') | components/user_manager/user.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
index e2e49ef4c4ab7e7f6688b66afd2b4e6f5e9cf251..2b7b98895cbc61863f2137002bcaa0fc51e2e1b8 100644
--- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
+++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
@@ -15,6 +15,7 @@
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
+#include "base/path_service.h"
#include "base/sha1.h"
#include "base/strings/string_number_conversions.h"
#include "base/sys_info.h"
@@ -29,6 +30,7 @@
#include "chrome/browser/chromeos/login/startup_utils.h"
#include "chrome/browser/chromeos/login/users/avatar/user_image_loader.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
+#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#include "chrome/browser/image_decoder.h"
#include "chrome/browser/ui/ash/ash_util.h"
#include "chrome/common/chrome_paths.h"
@@ -49,7 +51,9 @@
#include "content/public/browser/notification_service.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/service_manager_connection.h"
+#include "crypto/sha2.h"
#include "services/service_manager/public/cpp/connector.h"
+#include "url/gurl.h"
using content::BrowserThread;
using wallpaper::WallpaperManagerBase;
@@ -78,6 +82,11 @@ const char kNewWallpaperTypeNodeName[] = "type";
// Known user keys.
const char kWallpaperFilesId[] = "wallpaper-files-id";
+// The directory and file name to save the downloaded device policy controlled
+// wallpaper.
+const char kDeviceWallpaperDir[] = "device_wallpaper";
+const char kDeviceWallpaperFile[] = "device_wallpaper_image.jpg";
+
// These global default values are used to set customized default
// wallpaper path in WallpaperManager::InitializeWallpaper().
base::FilePath GetCustomizedWallpaperDefaultRescaledFileName(
@@ -195,6 +204,21 @@ void SetWallpaper(const gfx::ImageSkia& image,
}
}
+// A helper function to check the existing/downloaded device wallpaper file's
+// hash value matches with the hash value provided in the policy settings.
+bool CheckDeviceWallpaperMatchHash(const base::FilePath& device_wallpaper_file,
+ const std::string& hash) {
+ std::string image_data;
+ if (base::ReadFileToString(device_wallpaper_file, &image_data)) {
+ std::string sha_hash = crypto::SHA256HashString(image_data);
+ if (base::ToLowerASCII(base::HexEncode(
+ sha_hash.c_str(), sha_hash.size())) == base::ToLowerASCII(hash)) {
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace
// This is "wallpaper either scheduled to load, or loading right now".
@@ -347,6 +371,7 @@ class WallpaperManager::PendingWallpaper :
WallpaperManager::~WallpaperManager() {
show_user_name_on_signin_subscription_.reset();
+ device_wallpaper_image_subscription_.reset();
user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
weak_factory_.InvalidateWeakPtrs();
}
@@ -386,6 +411,11 @@ void WallpaperManager::AddObservers() {
kAccountsPrefShowUserNamesOnSignIn,
base::Bind(&WallpaperManager::InitializeRegisteredDeviceWallpaper,
weak_factory_.GetWeakPtr()));
+ device_wallpaper_image_subscription_ =
+ CrosSettings::Get()->AddSettingsObserver(
+ kDeviceWallpaperImage,
+ base::Bind(&WallpaperManager::OnDeviceWallpaperPolicyChanged,
+ weak_factory_.GetWeakPtr()));
}
void WallpaperManager::EnsureLoggedInUserWallpaperLoaded() {
@@ -697,6 +727,12 @@ void WallpaperManager::ScheduleSetUserWallpaper(const AccountId& account_id,
return;
}
+ // For a enterprise managed user, set the device wallpaper if we're at the
+ // login screen.
+ if (!user_manager::UserManager::Get()->IsUserLoggedIn() &&
+ SetDeviceWallpaperIfApplicable(account_id))
+ return;
+
// Guest user or regular user in ephemeral mode.
if ((user_manager::UserManager::Get()->IsUserNonCryptohomeDataEphemeral(
account_id) &&
@@ -734,16 +770,23 @@ void WallpaperManager::ScheduleSetUserWallpaper(const AccountId& account_id,
}
if (info.type == user_manager::User::CUSTOMIZED ||
- info.type == user_manager::User::POLICY) {
- const char* sub_dir = GetCustomWallpaperSubdirForCurrentResolution();
- // Wallpaper is not resized when layout is
- // wallpaper::WALLPAPER_LAYOUT_CENTER.
- // Original wallpaper should be used in this case.
- // TODO(bshe): Generates cropped custom wallpaper for CENTER layout.
- if (info.layout == wallpaper::WALLPAPER_LAYOUT_CENTER)
- sub_dir = wallpaper::kOriginalWallpaperSubDir;
- base::FilePath wallpaper_path = GetCustomWallpaperDir(sub_dir);
- wallpaper_path = wallpaper_path.Append(info.location);
+ info.type == user_manager::User::POLICY ||
+ info.type == user_manager::User::DEVICE) {
+ base::FilePath wallpaper_path;
+ if (info.type != user_manager::User::DEVICE) {
+ const char* sub_dir = GetCustomWallpaperSubdirForCurrentResolution();
+ // Wallpaper is not resized when layout is
+ // wallpaper::WALLPAPER_LAYOUT_CENTER.
+ // Original wallpaper should be used in this case.
+ // TODO(bshe): Generates cropped custom wallpaper for CENTER layout.
+ if (info.layout == wallpaper::WALLPAPER_LAYOUT_CENTER)
+ sub_dir = wallpaper::kOriginalWallpaperSubDir;
+ wallpaper_path = GetCustomWallpaperDir(sub_dir);
+ wallpaper_path = wallpaper_path.Append(info.location);
+ } else {
+ wallpaper_path = GetDeviceWallpaperFilePath();
+ }
+
CustomWallpaperMap::iterator it = wallpaper_cache_.find(account_id);
// Do not try to load the wallpaper if the path is the same. Since loading
// could still be in progress, we ignore the existence of the image.
@@ -891,6 +934,114 @@ void WallpaperManager::SetPolicyControlledWallpaper(
true /* update wallpaper */);
}
+void WallpaperManager::OnDeviceWallpaperPolicyChanged() {
+ SetDeviceWallpaperIfApplicable(
+ user_manager::UserManager::Get()->IsUserLoggedIn()
+ ? user_manager::UserManager::Get()->GetActiveUser()->GetAccountId()
+ : user_manager::SignInAccountId());
+}
+
+void WallpaperManager::OnDeviceWallpaperExists(const AccountId& account_id,
+ const std::string& url,
+ const std::string& hash,
+ bool exist) {
+ if (exist) {
+ base::PostTaskAndReplyWithResult(
+ BrowserThread::GetBlockingPool(), FROM_HERE,
+ base::Bind(&CheckDeviceWallpaperMatchHash, GetDeviceWallpaperFilePath(),
+ hash),
+ base::Bind(&WallpaperManager::OnCheckDeviceWallpaperMatchHash,
+ weak_factory_.GetWeakPtr(), account_id, url, hash));
+ } else {
+ GURL device_wallpaper_url(url);
+ device_wallpaper_downloader_.reset(new CustomizationWallpaperDownloader(
+ g_browser_process->system_request_context(), device_wallpaper_url,
+ GetDeviceWallpaperDir(), GetDeviceWallpaperFilePath(),
+ base::Bind(&WallpaperManager::OnDeviceWallpaperDownloaded,
+ weak_factory_.GetWeakPtr(), account_id, hash)));
+ device_wallpaper_downloader_->Start();
+ }
+}
+
+void WallpaperManager::OnDeviceWallpaperDownloaded(const AccountId& account_id,
+ const std::string& hash,
+ bool success,
+ const GURL& url) {
+ if (!success) {
+ LOG(ERROR) << "Failed to download the device wallpaper. Fallback to "
+ "default wallpaper.";
+ SetDefaultWallpaperDelayed(account_id);
+ return;
+ }
+
+ base::PostTaskAndReplyWithResult(
+ BrowserThread::GetBlockingPool(), FROM_HERE,
+ base::Bind(&CheckDeviceWallpaperMatchHash, GetDeviceWallpaperFilePath(),
+ hash),
+ base::Bind(&WallpaperManager::OnCheckDeviceWallpaperMatchHash,
+ weak_factory_.GetWeakPtr(), account_id, url.spec(), hash));
+}
+
+void WallpaperManager::OnCheckDeviceWallpaperMatchHash(
+ const AccountId& account_id,
+ const std::string& url,
+ const std::string& hash,
+ bool match) {
+ if (!match) {
+ if (retry_download_if_failed_) {
+ // We only retry to download the device wallpaper one more time if the
+ // hash doesn't match.
+ retry_download_if_failed_ = false;
+ GURL device_wallpaper_url(url);
+ device_wallpaper_downloader_.reset(new CustomizationWallpaperDownloader(
+ g_browser_process->system_request_context(), device_wallpaper_url,
+ GetDeviceWallpaperDir(), GetDeviceWallpaperFilePath(),
+ base::Bind(&WallpaperManager::OnDeviceWallpaperDownloaded,
+ weak_factory_.GetWeakPtr(), account_id, hash)));
+ device_wallpaper_downloader_->Start();
+ } else {
+ LOG(ERROR) << "The device wallpaper hash doesn't match with provided "
+ "hash value. Fallback to default wallpaper! ";
+ SetDefaultWallpaperDelayed(account_id);
+
+ // Reset the boolean variable so that it can retry to download when the
+ // next device wallpaper request comes in.
+ retry_download_if_failed_ = true;
+ }
+ return;
+ }
+
+ user_image_loader::StartWithFilePath(
+ task_runner_, GetDeviceWallpaperFilePath(),
+ ImageDecoder::ROBUST_JPEG_CODEC,
+ 0, // Do not crop.
+ base::Bind(&WallpaperManager::OnDeviceWallpaperDecoded,
+ weak_factory_.GetWeakPtr(), account_id));
+}
+
+void WallpaperManager::OnDeviceWallpaperDecoded(
+ const AccountId& account_id,
+ std::unique_ptr<user_manager::UserImage> user_image) {
+ WallpaperInfo wallpaper_info = {GetDeviceWallpaperFilePath().value(),
+ wallpaper::WALLPAPER_LAYOUT_CENTER_CROPPED,
+ user_manager::User::DEVICE,
+ base::Time::Now().LocalMidnight()};
+ if (user_manager::UserManager::Get()->IsUserLoggedIn()) {
+ // In a user's session treat the device wallpaper as a normal custom
+ // wallpaper. It should be persistent and can be overriden by other user
+ // selected wallpapers.
+ SetUserWallpaperInfo(account_id, wallpaper_info, true /* is_persistent */);
+ GetPendingWallpaper(account_id, false)
+ ->ResetSetWallpaperImage(user_image->image(), wallpaper_info);
+ wallpaper_cache_[account_id] = CustomWallpaperElement(
+ GetDeviceWallpaperFilePath(), user_image->image());
+ } else {
+ // In the login screen set the device wallpaper as the wallpaper.
+ GetPendingWallpaper(user_manager::SignInAccountId(), false)
+ ->ResetSetWallpaperImage(user_image->image(), wallpaper_info);
+ }
+}
+
void WallpaperManager::InitializeRegisteredDeviceWallpaper() {
if (user_manager::UserManager::Get()->IsUserLoggedIn())
return;
@@ -907,7 +1058,8 @@ void WallpaperManager::InitializeRegisteredDeviceWallpaper() {
int public_session_user_index = FindPublicSession(users);
if ((!show_users && public_session_user_index == -1) || users.empty()) {
// Boot into sign in form, preload default wallpaper.
- SetDefaultWallpaperDelayed(user_manager::SignInAccountId());
+ if (!SetDeviceWallpaperIfApplicable(user_manager::SignInAccountId()))
+ SetDefaultWallpaperDelayed(user_manager::SignInAccountId());
return;
}
@@ -966,6 +1118,53 @@ bool WallpaperManager::GetUserWallpaperInfo(const AccountId& account_id,
return true;
}
+bool WallpaperManager::ShouldSetDeviceWallpaper(const AccountId& account_id,
+ std::string* url,
+ std::string* hash) {
+ // Only allow the device wallpaper for enterprise managed devices.
+ if (!g_browser_process->platform_part()
+ ->browser_policy_connector_chromeos()
+ ->IsEnterpriseManaged()) {
+ return false;
+ }
+
+ const base::DictionaryValue* dict = nullptr;
+ if (!CrosSettings::Get()->GetDictionary(kDeviceWallpaperImage, &dict) ||
+ !dict->GetStringWithoutPathExpansion("url", url) ||
+ !dict->GetStringWithoutPathExpansion("hash", hash)) {
+ return false;
+ }
+
+ // Only set the device wallpaper if 1) we're at the login screen or 2) there
+ // is no user policy wallpaper in a user session and the user has the default
+ // wallpaper or device wallpaper in a user session. Note in the latter case,
+ // the device wallpaper can be overridden by user-selected wallpapers.
+ if (user_manager::UserManager::Get()->IsUserLoggedIn()) {
+ WallpaperInfo info;
+ if (GetUserWallpaperInfo(account_id, &info) &&
+ (info.type == user_manager::User::POLICY ||
+ (info.type != user_manager::User::DEFAULT &&
+ info.type != user_manager::User::DEVICE))) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+base::FilePath WallpaperManager::GetDeviceWallpaperDir() {
+ base::FilePath wallpaper_dir;
+ if (!PathService::Get(chrome::DIR_CHROMEOS_WALLPAPERS, &wallpaper_dir)) {
+ LOG(ERROR) << "Unable to get wallpaper dir.";
+ return base::FilePath();
+ }
+ return wallpaper_dir.Append(kDeviceWallpaperDir);
+}
+
+base::FilePath WallpaperManager::GetDeviceWallpaperFilePath() {
+ return GetDeviceWallpaperDir().Append(kDeviceWallpaperFile);
+}
+
void WallpaperManager::OnWallpaperDecoded(
const AccountId& account_id,
wallpaper::WallpaperLayout layout,
@@ -1071,6 +1270,36 @@ size_t WallpaperManager::GetPendingListSizeForTesting() const {
return loading_.size();
}
+wallpaper::WallpaperFilesId WallpaperManager::GetFilesId(
+ const AccountId& account_id) const {
+ std::string stored_value;
+ if (user_manager::known_user::GetStringPref(account_id, kWallpaperFilesId,
+ &stored_value)) {
+ return wallpaper::WallpaperFilesId::FromString(stored_value);
+ }
+ const std::string& old_id = account_id.GetUserEmail(); // Migrated
+ const wallpaper::WallpaperFilesId files_id = HashWallpaperFilesIdStr(old_id);
+ SetKnownUserWallpaperFilesId(account_id, files_id);
+ return files_id;
+}
+
+bool WallpaperManager::SetDeviceWallpaperIfApplicable(
+ const AccountId& account_id) {
+ std::string url;
+ std::string hash;
+ if (ShouldSetDeviceWallpaper(account_id, &url, &hash)) {
+ // Check if the device wallpaper exists and matches the hash. If so, use it
+ // directly. Otherwise download it first.
+ base::PostTaskAndReplyWithResult(
+ BrowserThread::GetBlockingPool(), FROM_HERE,
+ base::Bind(&base::PathExists, GetDeviceWallpaperFilePath()),
+ base::Bind(&WallpaperManager::OnDeviceWallpaperExists,
+ weak_factory_.GetWeakPtr(), account_id, url, hash));
+ return true;
+ }
+ return false;
+}
+
void WallpaperManager::UserChangedChildStatus(user_manager::User* user) {
SetUserWallpaperNow(user->GetAccountId());
}
@@ -1157,17 +1386,4 @@ void WallpaperManager::SetDefaultWallpaperPath(
DoSetDefaultWallpaper(EmptyAccountId(), MovableOnDestroyCallbackHolder());
}
-wallpaper::WallpaperFilesId WallpaperManager::GetFilesId(
- const AccountId& account_id) const {
- std::string stored_value;
- if (user_manager::known_user::GetStringPref(account_id, kWallpaperFilesId,
- &stored_value)) {
- return wallpaper::WallpaperFilesId::FromString(stored_value);
- }
- const std::string& old_id = account_id.GetUserEmail(); // Migrated
- const wallpaper::WallpaperFilesId files_id = HashWallpaperFilesIdStr(old_id);
- SetKnownUserWallpaperFilesId(account_id, files_id);
- return files_id;
-}
-
} // namespace chromeos
« no previous file with comments | « chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h ('k') | components/user_manager/user.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698