blob: 0a749262a32a16d8637a775a761c22786160e3e5 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chromeos/login/wallpaper_manager.h"
#include "ash/ash_switches.h"
#include "ash/desktop_background/desktop_background_controller.h"
#include "ash/desktop_background/desktop_background_controller_observer.h"
#include "ash/desktop_background/desktop_background_controller_test_api.h"
#include "ash/display/display_manager.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/ash_test_helper.h"
#include "ash/test/display_manager_test_api.h"
#include "ash/test/test_user_wallpaper_delegate.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/prefs/scoped_user_pref_update.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chrome/browser/chromeos/login/user.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chromeos/chromeos_switches.h"
#include "content/public/test/test_utils.h"
#include "grit/ash_resources.h"
#include "ui/aura/env.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/point.h"
#include "ui/gfx/rect.h"
using namespace ash;
namespace chromeos {
namespace {
const int kLargeWallpaperResourceId = IDR_AURA_WALLPAPER_DEFAULT_LARGE;
const int kSmallWallpaperResourceId = IDR_AURA_WALLPAPER_DEFAULT_SMALL;
int kLargeWallpaperWidth = 256;
int kLargeWallpaperHeight = chromeos::kLargeWallpaperMaxHeight;
int kSmallWallpaperWidth = 256;
int kSmallWallpaperHeight = chromeos::kSmallWallpaperMaxHeight;
const char kTestUser1[] = "test1@domain.com";
const char kTestUser1Hash[] = "test1@domain.com-hash";
const char kTestUser2[] = "test2@domain.com";
const char kTestUser2Hash[] = "test2@domain.com-hash";
} // namespace
class WallpaperManagerBrowserTest : public InProcessBrowserTest,
public testing::WithParamInterface<bool> {
public:
WallpaperManagerBrowserTest () : controller_(NULL),
local_state_(NULL) {
}
virtual ~WallpaperManagerBrowserTest () {}
virtual void SetUpOnMainThread() OVERRIDE {
controller_ = ash::Shell::GetInstance()->desktop_background_controller();
local_state_ = g_browser_process->local_state();
DesktopBackgroundController::TestAPI(controller_)
.set_wallpaper_reload_delay_for_test(0);
UpdateDisplay("800x600");
}
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
command_line->AppendSwitch(switches::kLoginManager);
command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
if (GetParam())
command_line->AppendSwitch(::switches::kMultiProfiles);
}
virtual void CleanUpOnMainThread() OVERRIDE {
controller_ = NULL;
}
// Update the display configuration as given in |display_specs|. See
// ash::test::DisplayManagerTestApi::UpdateDisplay for more details.
void UpdateDisplay(const std::string& display_specs) {
ash::test::DisplayManagerTestApi display_manager_test_api(
ash::Shell::GetInstance()->display_manager());
display_manager_test_api.UpdateDisplay(display_specs);
LOG(ERROR) << "UpdateDisplay(display_specs='" << display_specs
<< "') done.";
WallpaperManager::GetAppropriateResolutionForTesting();
}
void WaitAsyncWallpaperLoadStarted() {
base::RunLoop().RunUntilIdle();
}
void WaitAsyncWallpaperLoadFinished() {
base::RunLoop().RunUntilIdle();
while (WallpaperManager::Get()->loading_.size()) {
base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
base::RunLoop().RunUntilIdle();
}
}
protected:
// Colors used for different default wallpapers by
// WriteWallpapers().
static const SkColor kLargeWallpaperColor = SK_ColorRED;
static const SkColor kSmallWallpaperColor = SK_ColorGREEN;
static const SkColor kLargeGuestWallpaperColor = SK_ColorBLUE;
static const SkColor kSmallGuestWallpaperColor = SK_ColorYELLOW;
// A color that can be passed to CreateImage(). Specifically chosen to not
// conflict with any of the default wallpaper colors.
static const SkColor kCustomWallpaperColor = SK_ColorMAGENTA;
// Dimension used for width and height of default wallpaper images. A
// small value is used to minimize the amount of time spent compressing
// and writing images.
static const int kWallpaperSize = 2;
// Return custom wallpaper path. Create directory if not exist.
base::FilePath GetCustomWallpaperPath(const char* sub_dir,
const std::string& username_hash,
const std::string& id) {
base::FilePath wallpaper_path =
WallpaperManager::Get()->GetCustomWallpaperPath(sub_dir,
username_hash,
id);
if (!base::DirectoryExists(wallpaper_path.DirName()))
base::CreateDirectory(wallpaper_path.DirName());
return wallpaper_path;
}
// Logs in |username|.
void LogIn(const std::string& username, const std::string& username_hash) {
UserManager::Get()->UserLoggedIn(username, username_hash, false);
WaitAsyncWallpaperLoadStarted();
}
// Saves bitmap |resource_id| to disk.
void SaveUserWallpaperData(const base::FilePath& wallpaper_path,
int resource_id) {
scoped_refptr<base::RefCountedStaticMemory> image_data(
ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale(
resource_id, ui::SCALE_FACTOR_100P));
int written = base::WriteFile(
wallpaper_path,
reinterpret_cast<const char*>(image_data->front()),
image_data->size());
EXPECT_EQ(static_cast<int>(image_data->size()), written);
}
int LoadedWallpapers() {
return WallpaperManager::Get()->loaded_wallpapers();
}
void ClearDisposableWallpaperCache() {
WallpaperManager::Get()->ClearDisposableWallpaperCache();
}
// Creates a test image of size 1x1.
gfx::ImageSkia CreateTestImage(int width, int height, SkColor color) {
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
bitmap.allocPixels();
bitmap.eraseColor(color);
return gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
}
// Writes a JPEG image of the specified size and color to |path|. Returns
// true on success.
bool WriteJPEGFile(const base::FilePath& path,
int width,
int height,
SkColor color) {
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height, 0);
bitmap.allocPixels();
bitmap.eraseColor(color);
const int kQuality = 80;
std::vector<unsigned char> output;
if (!gfx::JPEGCodec::Encode(
static_cast<const unsigned char*>(bitmap.getPixels()),
gfx::JPEGCodec::FORMAT_SkBitmap,
width,
height,
bitmap.rowBytes(),
kQuality,
&output)) {
LOG(ERROR) << "Unable to encode " << width << "x" << height << " bitmap";
return false;
}
size_t bytes_written = base::WriteFile(
path, reinterpret_cast<const char*>(&output[0]), output.size());
if (bytes_written != output.size()) {
LOG(ERROR) << "Wrote " << bytes_written << " byte(s) instead of "
<< output.size() << " to " << path.value();
return false;
}
return true;
}
// Initializes default wallpaper paths "*default_*file" and writes JPEG
// wallpaper images to them.
// Only needs to be called (once) by tests that want to test loading of
// default wallpapers.
void WriteWallpapers() {
wallpaper_dir_.reset(new base::ScopedTempDir);
ASSERT_TRUE(wallpaper_dir_->CreateUniqueTempDir());
std::vector<std::string> options;
options.push_back(std::string("WM_Test_cmdline"));
const base::FilePath small_file =
wallpaper_dir_->path().Append(FILE_PATH_LITERAL("small.jpg"));
options.push_back(std::string("--") +
ash::switches::kAshDefaultWallpaperSmall + "=" +
small_file.value());
const base::FilePath large_file =
wallpaper_dir_->path().Append(FILE_PATH_LITERAL("large.jpg"));
options.push_back(std::string("--") +
ash::switches::kAshDefaultWallpaperLarge + "=" +
large_file.value());
const base::FilePath guest_small_file =
wallpaper_dir_->path().Append(FILE_PATH_LITERAL("guest_small.jpg"));
options.push_back(std::string("--") +
ash::switches::kAshGuestWallpaperSmall + "=" +
guest_small_file.value());
const base::FilePath guest_large_file =
wallpaper_dir_->path().Append(FILE_PATH_LITERAL("guest_large.jpg"));
options.push_back(std::string("--") +
ash::switches::kAshGuestWallpaperLarge + "=" +
guest_large_file.value());
ASSERT_TRUE(WriteJPEGFile(small_file,
kWallpaperSize,
kWallpaperSize,
kSmallWallpaperColor));
ASSERT_TRUE(WriteJPEGFile(large_file,
kWallpaperSize,
kWallpaperSize,
kLargeWallpaperColor));
ASSERT_TRUE(WriteJPEGFile(guest_small_file,
kWallpaperSize,
kWallpaperSize,
kSmallGuestWallpaperColor));
ASSERT_TRUE(WriteJPEGFile(guest_large_file,
kWallpaperSize,
kWallpaperSize,
kLargeGuestWallpaperColor));
wallpaper_manager_command_line_.reset(new base::CommandLine(options));
WallpaperManager::Get()->SetCommandLineForTesting(
wallpaper_manager_command_line_.get());
}
// Returns true if the color at the center of |image| is close to
// |expected_color|. (The center is used so small wallpaper images can be
// used.)
bool ImageIsNearColor(gfx::ImageSkia image, SkColor expected_color) {
if (image.size().IsEmpty()) {
LOG(ERROR) << "Image is empty";
return false;
}
const SkBitmap* bitmap = image.bitmap();
if (!bitmap) {
LOG(ERROR) << "Unable to get bitmap from image";
return false;
}
bitmap->lockPixels();
gfx::Point center = gfx::Rect(image.size()).CenterPoint();
SkColor image_color = bitmap->getColor(center.x(), center.y());
bitmap->unlockPixels();
const int kDiff = 3;
if (std::abs(static_cast<int>(SkColorGetA(image_color)) -
static_cast<int>(SkColorGetA(expected_color))) > kDiff ||
std::abs(static_cast<int>(SkColorGetR(image_color)) -
static_cast<int>(SkColorGetR(expected_color))) > kDiff ||
std::abs(static_cast<int>(SkColorGetG(image_color)) -
static_cast<int>(SkColorGetG(expected_color))) > kDiff ||
std::abs(static_cast<int>(SkColorGetB(image_color)) -
static_cast<int>(SkColorGetB(expected_color))) > kDiff) {
LOG(ERROR) << "Expected color near 0x" << std::hex << expected_color
<< " but got 0x" << image_color;
return false;
}
return true;
}
DesktopBackgroundController* controller_;
PrefService* local_state_;
scoped_ptr<base::CommandLine> wallpaper_manager_command_line_;
// Directory created by WriteWallpapersAndSetFlags() to store default
// wallpaper images.
scoped_ptr<base::ScopedTempDir> wallpaper_dir_;
private:
DISALLOW_COPY_AND_ASSIGN(WallpaperManagerBrowserTest);
};
// Tests that the appropriate custom wallpaper (large vs. small) is loaded
// depending on the desktop resolution.
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTest,
LoadCustomLargeWallpaperForLargeExternalScreen) {
WallpaperManager* wallpaper_manager = WallpaperManager::Get();
LogIn(kTestUser1, kTestUser1Hash);
std::string id = base::Int64ToString(base::Time::Now().ToInternalValue());
base::FilePath small_wallpaper_path = GetCustomWallpaperPath(
kSmallWallpaperSubDir,
kTestUser1Hash,
id);
base::FilePath large_wallpaper_path = GetCustomWallpaperPath(
kLargeWallpaperSubDir,
kTestUser1Hash,
id);
// Saves the small/large resolution wallpapers to small/large custom
// wallpaper paths.
SaveUserWallpaperData(small_wallpaper_path,
kSmallWallpaperResourceId);
SaveUserWallpaperData(large_wallpaper_path,
kLargeWallpaperResourceId);
std::string relative_path = base::FilePath(kTestUser1Hash).Append(id).value();
// Saves wallpaper info to local state for user |kTestUser1|.
WallpaperInfo info = {
relative_path,
WALLPAPER_LAYOUT_CENTER_CROPPED,
User::CUSTOMIZED,
base::Time::Now().LocalMidnight()
};
wallpaper_manager->SetUserWallpaperInfo(kTestUser1, info, true);
// Set the wallpaper for |kTestUser1|.
wallpaper_manager->SetUserWallpaperNow(kTestUser1);
WaitAsyncWallpaperLoadFinished();
gfx::ImageSkia wallpaper = controller_->GetWallpaper();
// Display is initialized to 800x600. The small resolution custom wallpaper is
// expected.
EXPECT_EQ(kSmallWallpaperWidth, wallpaper.width());
EXPECT_EQ(kSmallWallpaperHeight, wallpaper.height());
// Hook up another 800x600 display. This shouldn't trigger a reload.
UpdateDisplay("800x600,800x600");
WaitAsyncWallpaperLoadFinished();
// The small resolution custom wallpaper is expected.
EXPECT_EQ(kSmallWallpaperWidth, wallpaper.width());
EXPECT_EQ(kSmallWallpaperHeight, wallpaper.height());
// Detach the secondary display.
UpdateDisplay("800x600");
// Hook up a 2000x2000 display. The large resolution custom wallpaper should
// be loaded.
UpdateDisplay("800x600,2000x2000");
WaitAsyncWallpaperLoadFinished();
wallpaper = controller_->GetWallpaper();
// The large resolution custom wallpaper is expected.
EXPECT_EQ(kLargeWallpaperWidth, wallpaper.width());
EXPECT_EQ(kLargeWallpaperHeight, wallpaper.height());
// Detach the secondary display.
UpdateDisplay("800x600");
// Hook up the 2000x2000 display again. The large resolution default wallpaper
// should persist. Test for crbug/165788.
UpdateDisplay("800x600,2000x2000");
WaitAsyncWallpaperLoadFinished();
wallpaper = controller_->GetWallpaper();
// The large resolution custom wallpaper is expected.
EXPECT_EQ(kLargeWallpaperWidth, wallpaper.width());
EXPECT_EQ(kLargeWallpaperHeight, wallpaper.height());
}
// If chrome tries to reload the same wallpaper twice, the latter request should
// be prevented. Otherwise, there are some strange animation issues as
// described in crbug.com/158383.
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTest,
PreventReloadingSameWallpaper) {
WallpaperManager* wallpaper_manager = WallpaperManager::Get();
// New user log in, a default wallpaper is loaded.
LogIn(kTestUser1, kTestUser1Hash);
EXPECT_EQ(1, LoadedWallpapers());
// Loads the same wallpaper before the initial one finished. It should be
// prevented.
wallpaper_manager->SetUserWallpaperNow(kTestUser1);
WaitAsyncWallpaperLoadFinished();
EXPECT_EQ(1, LoadedWallpapers());
// Loads the same wallpaper after the initial one finished. It should be
// prevented.
wallpaper_manager->SetUserWallpaperNow(kTestUser1);
WaitAsyncWallpaperLoadFinished();
EXPECT_EQ(1, LoadedWallpapers());
ClearDisposableWallpaperCache();
// Change wallpaper to a custom wallpaper.
std::string id = base::Int64ToString(base::Time::Now().ToInternalValue());
base::FilePath small_wallpaper_path = GetCustomWallpaperPath(
kSmallWallpaperSubDir,
kTestUser1Hash,
id);
SaveUserWallpaperData(small_wallpaper_path,
kSmallWallpaperResourceId);
std::string relative_path = base::FilePath(kTestUser1Hash).Append(id).value();
// Saves wallpaper info to local state for user |kTestUser1|.
WallpaperInfo info = {
relative_path,
WALLPAPER_LAYOUT_CENTER_CROPPED,
User::CUSTOMIZED,
base::Time::Now().LocalMidnight()
};
wallpaper_manager->SetUserWallpaperInfo(kTestUser1, info, true);
wallpaper_manager->SetUserWallpaperNow(kTestUser1);
WaitAsyncWallpaperLoadStarted();
EXPECT_EQ(2, LoadedWallpapers());
// Loads the same wallpaper before the initial one finished. It should be
// prevented.
wallpaper_manager->SetUserWallpaperNow(kTestUser1);
WaitAsyncWallpaperLoadStarted();
EXPECT_EQ(2, LoadedWallpapers());
wallpaper_manager->SetUserWallpaperNow(kTestUser1);
WaitAsyncWallpaperLoadFinished();
EXPECT_EQ(2, LoadedWallpapers());
}
// Some users have old user profiles which may have legacy wallpapers. And these
// lagacy wallpapers should migrate to new wallpaper picker version seamlessly.
// This tests make sure we compatible with migrated old wallpapers.
// crosbug.com/38429
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTest,
PRE_UseMigratedWallpaperInfo) {
// New user log in, a default wallpaper is loaded.
LogIn(kTestUser1, kTestUser1Hash);
// Old wallpaper migration code doesn't exist in codebase anymore. Modify user
// wallpaper info directly to simulate the wallpaper migration. See
// crosbug.com/38429 for details about why we modify wallpaper info this way.
WallpaperInfo info = {
"123",
WALLPAPER_LAYOUT_CENTER_CROPPED,
User::DEFAULT,
base::Time::Now().LocalMidnight()
};
base::FilePath user_data_dir;
ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
SaveUserWallpaperData(user_data_dir.Append("123"),
kLargeWallpaperResourceId);
WallpaperManager::Get()->SetUserWallpaperInfo(kTestUser1, info, true);
}
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTest,
UseMigratedWallpaperInfo) {
LogIn(kTestUser1, kTestUser1Hash);
WaitAsyncWallpaperLoadFinished();
// This test should finish normally. If timeout, it is probably because
// migrated wallpaper is somehow not loaded. Bad things can happen if
// wallpaper is not loaded at login screen. One example is: crosbug.com/38429.
}
// Some users have old user profiles which may never get a chance to migrate.
// This tests make sure we compatible with these profiles.
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTest,
PRE_UsePreMigrationWallpaperInfo) {
// New user log in, a default wallpaper is loaded.
LogIn(kTestUser1, kTestUser1Hash);
// Old wallpaper migration code doesn't exist in codebase anymore. So if
// user's profile is not migrated, it is the same as no wallpaper info. To
// simulate this, we remove user's wallpaper info here.
WallpaperManager::Get()->RemoveUserWallpaperInfo(kTestUser1);
}
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTest,
UsePreMigrationWallpaperInfo) {
LogIn(kTestUser1, kTestUser1Hash);
WaitAsyncWallpaperLoadFinished();
// This test should finish normally. If timeout, it is probably because chrome
// can not handle pre migrated user profile (M21 profile or older).
}
// Test for http://crbug.com/265689. When hooked up a large external monitor,
// the default large resolution wallpaper should load.
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTest,
HotPlugInScreenAtGAIALoginScreen) {
UpdateDisplay("800x600");
// Set initial wallpaper to the default wallpaper.
WallpaperManager::Get()->SetDefaultWallpaperNow(UserManager::kStubUser);
WaitAsyncWallpaperLoadFinished();
// Hook up a 2000x2000 display. The large resolution custom wallpaper should
// be loaded.
UpdateDisplay("800x600,2000x2000");
WaitAsyncWallpaperLoadFinished();
}
class WallpaperManagerBrowserTestNoAnimation
: public WallpaperManagerBrowserTest {
public:
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
command_line->AppendSwitch(switches::kLoginManager);
command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
command_line->AppendSwitch(chromeos::switches::kDisableLoginAnimations);
command_line->AppendSwitch(chromeos::switches::kDisableBootAnimation);
}
};
// Same test as WallpaperManagerBrowserTest.UseMigratedWallpaperInfo. But
// disabled boot and login animation.
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTestNoAnimation,
PRE_UseMigratedWallpaperInfo) {
// New user log in, a default wallpaper is loaded.
LogIn(kTestUser1, kTestUser1Hash);
// Old wallpaper migration code doesn't exist in codebase anymore. Modify user
// wallpaper info directly to simulate the wallpaper migration. See
// crosbug.com/38429 for details about why we modify wallpaper info this way.
WallpaperInfo info = {
"123",
WALLPAPER_LAYOUT_CENTER_CROPPED,
User::DEFAULT,
base::Time::Now().LocalMidnight()
};
base::FilePath user_data_dir;
ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
SaveUserWallpaperData(user_data_dir.Append("123"),
kLargeWallpaperResourceId);
WallpaperManager::Get()->SetUserWallpaperInfo(kTestUser1, info, true);
}
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTestNoAnimation,
UseMigratedWallpaperInfo) {
LogIn(kTestUser1, kTestUser1Hash);
WaitAsyncWallpaperLoadFinished();
// This test should finish normally. If timeout, it is probably because
// migrated wallpaper is somehow not loaded. Bad things can happen if
// wallpaper is not loaded at login screen. One example is: crosbug.com/38429.
}
// Same test as WallpaperManagerBrowserTest.UsePreMigrationWallpaperInfo. But
// disabled boot and login animation.
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTestNoAnimation,
PRE_UsePreMigrationWallpaperInfo) {
// New user log in, a default wallpaper is loaded.
LogIn(kTestUser1, kTestUser1Hash);
WaitAsyncWallpaperLoadFinished();
// Old wallpaper migration code doesn't exist in codebase anymore. So if
// user's profile is not migrated, it is the same as no wallpaper info. To
// simulate this, we remove user's wallpaper info here.
WallpaperManager::Get()->RemoveUserWallpaperInfo(kTestUser1);
}
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTestNoAnimation,
UsePreMigrationWallpaperInfo) {
LogIn(kTestUser1, kTestUser1Hash);
WaitAsyncWallpaperLoadFinished();
// This test should finish normally. If timeout, it is probably because chrome
// can not handle pre migrated user profile (M21 profile or older).
}
class WallpaperManagerBrowserTestCrashRestore
: public WallpaperManagerBrowserTest {
public:
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
command_line->AppendSwitch(chromeos::switches::kDisableLoginAnimations);
command_line->AppendSwitch(chromeos::switches::kDisableBootAnimation);
command_line->AppendSwitch(::switches::kMultiProfiles);
command_line->AppendSwitchASCII(switches::kLoginUser, kTestUser1);
command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
}
};
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTestCrashRestore,
PRE_RestoreWallpaper) {
LogIn(kTestUser1, kTestUser1Hash);
WaitAsyncWallpaperLoadFinished();
}
// Test for crbug.com/270278. It simulates a browser crash and verifies if user
// wallpaper is loaded.
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTestCrashRestore,
RestoreWallpaper) {
EXPECT_EQ(1, LoadedWallpapers());
}
class WallpaperManagerBrowserTestCacheUpdate
: public WallpaperManagerBrowserTest {
public:
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
command_line->AppendSwitch(::switches::kMultiProfiles);
command_line->AppendSwitchASCII(switches::kLoginUser, kTestUser1);
command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
}
protected:
// Creates a test image of size 1x1.
gfx::ImageSkia CreateTestImage(SkColor color) {
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
bitmap.allocPixels();
bitmap.eraseColor(color);
return gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
}
};
// Sets kTestUser1's wallpaper to a custom wallpaper.
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTestCacheUpdate,
PRE_VerifyWallpaperCache) {
// Add kTestUser1 to user list. kTestUser1 is the default login profile.
LogIn(kTestUser1, kTestUser1Hash);
std::string id = base::Int64ToString(base::Time::Now().ToInternalValue());
WallpaperManager* wallpaper_manager = WallpaperManager::Get();
base::FilePath small_wallpaper_path = GetCustomWallpaperPath(
kSmallWallpaperSubDir,
kTestUser1Hash,
id);
base::FilePath large_wallpaper_path = GetCustomWallpaperPath(
kLargeWallpaperSubDir,
kTestUser1Hash,
id);
// Saves the small/large resolution wallpapers to small/large custom
// wallpaper paths.
SaveUserWallpaperData(small_wallpaper_path,
kSmallWallpaperResourceId);
SaveUserWallpaperData(large_wallpaper_path,
kLargeWallpaperResourceId);
std::string relative_path = base::FilePath(kTestUser1Hash).Append(id).value();
// Saves wallpaper info to local state for user |kTestUser1|.
WallpaperInfo info = {
relative_path,
WALLPAPER_LAYOUT_CENTER_CROPPED,
User::CUSTOMIZED,
base::Time::Now().LocalMidnight()
};
wallpaper_manager->SetUserWallpaperInfo(kTestUser1, info, true);
wallpaper_manager->SetUserWallpaperNow(kTestUser1);
WaitAsyncWallpaperLoadFinished();
scoped_ptr<WallpaperManager::TestApi> test_api;
test_api.reset(new WallpaperManager::TestApi(wallpaper_manager));
// Verify SetUserWallpaperNow updates wallpaper cache.
gfx::ImageSkia cached_wallpaper;
EXPECT_TRUE(test_api->GetWallpaperFromCache(kTestUser1, &cached_wallpaper));
}
// Tests for crbug.com/339576. Wallpaper cache should be updated in
// multi-profile mode when user:
// 1. chooses an online wallpaper from wallpaper
// picker (calls SetWallpaperFromImageSkia);
// 2. chooses a custom wallpaper from wallpaper
// picker (calls SetCustomWallpaper);
// 3. reverts to a default wallpaper.
// Also, when user login at multi-profile mode, previous logged in users'
// wallpaper cache should not be deleted.
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTestCacheUpdate,
VerifyWallpaperCache) {
WaitAsyncWallpaperLoadFinished();
WallpaperManager* wallpaper_manager = WallpaperManager::Get();
scoped_ptr<WallpaperManager::TestApi> test_api;
test_api.reset(new WallpaperManager::TestApi(wallpaper_manager));
gfx::ImageSkia cached_wallpaper;
// Previous custom wallpaper should be cached after user login.
EXPECT_TRUE(test_api->GetWallpaperFromCache(kTestUser1, &cached_wallpaper));
LogIn(kTestUser2, kTestUser2Hash);
WaitAsyncWallpaperLoadFinished();
// Login another user should not delete logged in user's wallpaper cache.
// Note active user is still kTestUser1.
EXPECT_TRUE(test_api->GetWallpaperFromCache(kTestUser1, &cached_wallpaper));
gfx::ImageSkia red_wallpaper = CreateTestImage(SK_ColorRED);
wallpaper_manager->SetWallpaperFromImageSkia(kTestUser1,
red_wallpaper,
WALLPAPER_LAYOUT_CENTER,
true);
WaitAsyncWallpaperLoadFinished();
// SetWallpaperFromImageSkia should update wallpaper cache when multi-profile
// is turned on.
EXPECT_TRUE(test_api->GetWallpaperFromCache(kTestUser1, &cached_wallpaper));
EXPECT_TRUE(cached_wallpaper.BackedBySameObjectAs(red_wallpaper));
gfx::ImageSkia green_wallpaper = CreateTestImage(SK_ColorGREEN);
wallpaper_manager->SetCustomWallpaper(kTestUser1,
kTestUser1Hash,
"dummy", // dummy file name
WALLPAPER_LAYOUT_CENTER,
User::CUSTOMIZED,
green_wallpaper,
true);
WaitAsyncWallpaperLoadFinished();
// SetCustomWallpaper should also update wallpaper cache when multi-profile is
// turned on.
EXPECT_TRUE(test_api->GetWallpaperFromCache(kTestUser1, &cached_wallpaper));
EXPECT_TRUE(cached_wallpaper.BackedBySameObjectAs(green_wallpaper));
wallpaper_manager->SetDefaultWallpaperNow(kTestUser1);
WaitAsyncWallpaperLoadFinished();
// SetDefaultWallpaper should invalidate the user's wallpaper cache.
EXPECT_FALSE(test_api->GetWallpaperFromCache(kTestUser1, &cached_wallpaper));
}
INSTANTIATE_TEST_CASE_P(WallpaperManagerBrowserTestInstantiation,
WallpaperManagerBrowserTest,
testing::Bool());
INSTANTIATE_TEST_CASE_P(WallpaperManagerBrowserTestNoAnimationInstantiation,
WallpaperManagerBrowserTestNoAnimation,
testing::Bool());
INSTANTIATE_TEST_CASE_P(WallpaperManagerBrowserTestCrashRestoreInstantiation,
WallpaperManagerBrowserTestCrashRestore,
testing::Bool());
INSTANTIATE_TEST_CASE_P(WallpaperManagerBrowserTestCacheUpdateInstantiation,
WallpaperManagerBrowserTestCacheUpdate,
testing::Bool());
// ----------------------------------------------------------------------
// Test default wallpapers.
class TestObserver : public WallpaperManager::Observer {
public:
explicit TestObserver(WallpaperManager* wallpaper_manager)
: update_wallpaper_count_(0), wallpaper_manager_(wallpaper_manager) {
DCHECK(wallpaper_manager_);
wallpaper_manager_->AddObserver(this);
}
virtual ~TestObserver() {
wallpaper_manager_->RemoveObserver(this);
}
virtual void OnWallpaperAnimationFinished(const std::string&) OVERRIDE {
}
virtual void OnUpdateWallpaperForTesting() OVERRIDE {
++update_wallpaper_count_;
}
int GetUpdateWallpaperCountAndReset() {
const size_t old = update_wallpaper_count_;
update_wallpaper_count_ = 0;
return old;
}
private:
int update_wallpaper_count_;
WallpaperManager* wallpaper_manager_;
DISALLOW_COPY_AND_ASSIGN(TestObserver);
};
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTest, DisplayChange) {
// TODO(derat|oshima|bshe): Host windows can't be resized on Win8.
if (!ash::test::AshTestHelper::SupportsHostWindowResize())
return;
TestObserver observer(WallpaperManager::Get());
// Set the wallpaper to ensure that UpdateWallpaper() will be called when the
// display configuration changes.
gfx::ImageSkia image = CreateTestImage(640, 480, kCustomWallpaperColor);
controller_->SetWallpaperImage(image, WALLPAPER_LAYOUT_STRETCH);
// Small wallpaper images should be used for configurations less than or
// equal to kSmallWallpaperMaxWidth by kSmallWallpaperMaxHeight, even if
// multiple displays are connected.
UpdateDisplay("800x600");
WaitAsyncWallpaperLoadFinished();
WallpaperManager::GetAppropriateResolutionForTesting();
EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_SMALL,
WallpaperManager::Get()->GetAppropriateResolution());
EXPECT_EQ(0, observer.GetUpdateWallpaperCountAndReset());
UpdateDisplay("800x600,800x600");
WaitAsyncWallpaperLoadFinished();
WallpaperManager::GetAppropriateResolutionForTesting();
EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_SMALL,
WallpaperManager::Get()->GetAppropriateResolution());
EXPECT_EQ(0, observer.GetUpdateWallpaperCountAndReset());
UpdateDisplay("1366x800");
WaitAsyncWallpaperLoadFinished();
WallpaperManager::GetAppropriateResolutionForTesting();
EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_SMALL,
WallpaperManager::Get()->GetAppropriateResolution());
EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
// At larger sizes, large wallpapers should be used.
UpdateDisplay("1367x800");
WaitAsyncWallpaperLoadFinished();
WallpaperManager::GetAppropriateResolutionForTesting();
EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_LARGE,
WallpaperManager::Get()->GetAppropriateResolution());
EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
UpdateDisplay("1367x801");
WaitAsyncWallpaperLoadFinished();
WallpaperManager::GetAppropriateResolutionForTesting();
EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_LARGE,
WallpaperManager::Get()->GetAppropriateResolution());
EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
UpdateDisplay("2560x1700");
WaitAsyncWallpaperLoadFinished();
WallpaperManager::GetAppropriateResolutionForTesting();
EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_LARGE,
WallpaperManager::Get()->GetAppropriateResolution());
EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
// Rotated smaller screen may use larger image.
UpdateDisplay("800x600/r");
WaitAsyncWallpaperLoadFinished();
WallpaperManager::GetAppropriateResolutionForTesting();
EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_SMALL,
WallpaperManager::Get()->GetAppropriateResolution());
EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
UpdateDisplay("800x600/r,800x600");
WaitAsyncWallpaperLoadFinished();
WallpaperManager::GetAppropriateResolutionForTesting();
EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_SMALL,
WallpaperManager::Get()->GetAppropriateResolution());
EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
UpdateDisplay("1366x800/r");
WallpaperManager::GetAppropriateResolutionForTesting();
WaitAsyncWallpaperLoadFinished();
EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_LARGE,
WallpaperManager::Get()->GetAppropriateResolution());
EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
// Max display size didn't chagne.
UpdateDisplay("900x800/r,400x1366");
WallpaperManager::GetAppropriateResolutionForTesting();
WaitAsyncWallpaperLoadFinished();
EXPECT_EQ(0, observer.GetUpdateWallpaperCountAndReset());
}
// Test that WallpaperManager loads the appropriate wallpaper
// images as specified via command-line flags in various situations.
// Splitting these into separate tests avoids needing to run animations.
// TODO(derat): Combine these into a single test
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTest, SmallDefaultWallpaper) {
if (!ash::test::AshTestHelper::SupportsMultipleDisplays())
return;
WriteWallpapers();
// At 800x600, the small wallpaper should be loaded.
UpdateDisplay("800x600");
WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
WaitAsyncWallpaperLoadFinished();
EXPECT_TRUE(
ImageIsNearColor(controller_->GetWallpaper(), kSmallWallpaperColor));
}
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTest, LargeDefaultWallpaper) {
if (!ash::test::AshTestHelper::SupportsMultipleDisplays())
return;
WriteWallpapers();
UpdateDisplay("1600x1200");
WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
WaitAsyncWallpaperLoadFinished();
EXPECT_TRUE(
ImageIsNearColor(controller_->GetWallpaper(), kLargeWallpaperColor));
}
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTest,
LargeDefaultWallpaperWhenRotated) {
if (!ash::test::AshTestHelper::SupportsMultipleDisplays())
return;
WriteWallpapers();
UpdateDisplay("1200x800/r");
WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
WaitAsyncWallpaperLoadFinished();
EXPECT_TRUE(
ImageIsNearColor(controller_->GetWallpaper(), kLargeWallpaperColor));
}
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTest, SmallGuestWallpaper) {
if (!ash::test::AshTestHelper::SupportsMultipleDisplays())
return;
WriteWallpapers();
UserManager::Get()->UserLoggedIn(
UserManager::kGuestUserName, UserManager::kGuestUserName, false);
UpdateDisplay("800x600");
WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
WaitAsyncWallpaperLoadFinished();
EXPECT_TRUE(
ImageIsNearColor(controller_->GetWallpaper(), kSmallGuestWallpaperColor));
}
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTest, LargeGuestWallpaper) {
if (!ash::test::AshTestHelper::SupportsMultipleDisplays())
return;
WriteWallpapers();
UserManager::Get()->UserLoggedIn(
UserManager::kGuestUserName, UserManager::kGuestUserName, false);
UpdateDisplay("1600x1200");
WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
WaitAsyncWallpaperLoadFinished();
EXPECT_TRUE(
ImageIsNearColor(controller_->GetWallpaper(), kLargeGuestWallpaperColor));
}
IN_PROC_BROWSER_TEST_P(WallpaperManagerBrowserTest,
SwitchBetweenDefaultAndCustom) {
// Start loading the default wallpaper.
UpdateDisplay("640x480");
WriteWallpapers();
UserManager::Get()->UserLoggedIn(UserManager::kStubUser, "test_hash", false);
WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
// Custom wallpaper should be applied immediately, canceling the default
// wallpaper load task.
gfx::ImageSkia image = CreateTestImage(640, 480, kCustomWallpaperColor);
WallpaperManager::Get()->SetCustomWallpaper(UserManager::kStubUser,
"test_hash",
"test-nofile.jpeg",
WALLPAPER_LAYOUT_STRETCH,
User::CUSTOMIZED,
image,
true);
WaitAsyncWallpaperLoadFinished();
EXPECT_TRUE(
ImageIsNearColor(controller_->GetWallpaper(), kCustomWallpaperColor));
WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
WaitAsyncWallpaperLoadFinished();
EXPECT_TRUE(
ImageIsNearColor(controller_->GetWallpaper(), kSmallWallpaperColor));
}
} // namespace chromeos