Chromium Code Reviews| Index: chrome/browser/ui/app_list/arc/arc_app_unittest.cc |
| diff --git a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc |
| index c72110be9266834b5876fdf0d31117ed3a98156a..6f725d74612ada7da798765906a8e1891220a5c2 100644 |
| --- a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc |
| +++ b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc |
| @@ -10,6 +10,7 @@ |
| #include "base/files/file_path.h" |
| #include "base/files/file_util.h" |
| #include "base/memory/scoped_vector.h" |
| +#include "base/path_service.h" |
| #include "base/run_loop.h" |
| #include "base/strings/string_util.h" |
| #include "base/task_runner_util.h" |
| @@ -23,16 +24,189 @@ |
| #include "components/arc/arc_bridge_service.h" |
| #include "components/arc/test/fake_arc_bridge_service.h" |
| #include "content/public/browser/browser_thread.h" |
| +#include "mojo/public/cpp/bindings/binding.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/app_list/app_list_model.h" |
| #include "ui/gfx/image/image_skia.h" |
| +namespace mojo { |
| + |
| +template <> |
| +struct TypeConverter<arc::AppInfoPtr, arc::AppInfo> { |
| + static arc::AppInfoPtr Convert(const arc::AppInfo& app_info) { |
| + return app_info.Clone(); |
| + } |
| +}; |
| + |
| +} // namespace mojo |
| + |
| namespace { |
| std::string GetAppId(const arc::AppInfo& app_info) { |
| return ArcAppListPrefs::GetAppId(app_info.package, app_info.activity); |
| } |
| +class FakeAppInstance : public arc::AppInstance { |
|
xiyuan
2015/12/14 22:52:02
nit: Think it would be better to put this into its
Luis Héctor Chávez
2015/12/16 17:07:22
Done.
|
| + public: |
| + class Request { |
| + public: |
| + Request(const std::string& package, const std::string& activity) |
| + : package_(package), activity_(activity) {} |
| + ~Request() {} |
| + |
| + const std::string& package() const { return package_; } |
| + |
| + const std::string& activity() const { return activity_; } |
| + |
| + bool IsForApp(const arc::AppInfo& app_info) const { |
| + return package_ == app_info.package && activity_ == app_info.activity; |
| + } |
| + |
| + private: |
| + std::string package_; |
| + std::string activity_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(Request); |
| + }; |
| + |
| + class IconRequest : public Request { |
| + public: |
| + IconRequest(const std::string& package, |
| + const std::string& activity, |
| + arc::ScaleFactor scale_factor) |
| + : Request(package, activity), scale_factor_(scale_factor) {} |
| + ~IconRequest() {} |
| + |
| + int scale_factor() const { return scale_factor_; } |
| + |
| + private: |
| + int scale_factor_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(IconRequest); |
| + }; |
| + |
| + explicit FakeAppInstance(arc::AppHost* app_host) |
| + : binding_(this), app_host_(app_host) {} |
| + ~FakeAppInstance() override {} |
| + |
| + void Bind(mojo::InterfaceRequest<arc::AppInstance> interface_request) { |
| + binding_.Bind(std::move(interface_request)); |
| + } |
| + |
| + // arc::AppInstance overrides: |
| + void Init(arc::AppHostPtr host_ptr) override {} |
| + void RefreshAppList() override; |
| + void LaunchApp(const mojo::String& package, |
| + const mojo::String& activity) override; |
| + void RequestAppIcon(const mojo::String& package, |
| + const mojo::String& activity, |
| + arc::ScaleFactor scale_factor) override; |
| + |
| + // Methods to reply messages. |
| + void SendRefreshAppList(const std::vector<arc::AppInfo>& apps); |
| + bool GenerateAndSendIcon(const arc::AppInfo& app, |
| + arc::ScaleFactor scale_factor, |
| + std::string* png_data_as_string); |
| + |
| + int refresh_app_list_count() const { return refresh_app_list_count_; } |
| + |
| + const ScopedVector<Request>& launch_requests() const { |
| + return launch_requests_; |
| + } |
| + |
| + const ScopedVector<IconRequest>& icon_requests() const { |
| + return icon_requests_; |
| + } |
| + |
| + private: |
| + // Mojo endpoints. |
| + mojo::Binding<arc::AppInstance> binding_; |
| + arc::AppHost* app_host_; |
| + // Number of RefreshAppList calls. |
| + int refresh_app_list_count_ = 0; |
| + // Keeps information about launch requests. |
| + ScopedVector<Request> launch_requests_; |
| + // Keeps information about icon load requests. |
| + ScopedVector<IconRequest> icon_requests_; |
| +}; |
| + |
| +void FakeAppInstance::RefreshAppList() { |
| + ++refresh_app_list_count_; |
| +} |
| + |
| +void FakeAppInstance::LaunchApp(const mojo::String& package, |
| + const mojo::String& activity) { |
| + launch_requests_.push_back(new Request(package, activity)); |
| +} |
| + |
| +void FakeAppInstance::RequestAppIcon(const mojo::String& package, |
| + const mojo::String& activity, |
| + arc::ScaleFactor scale_factor) { |
| + icon_requests_.push_back(new IconRequest(package, activity, scale_factor)); |
| +} |
| + |
| +void FakeAppInstance::SendRefreshAppList( |
| + const std::vector<arc::AppInfo>& apps) { |
| + app_host_->OnAppListRefreshed(mojo::Array<arc::AppInfoPtr>::From(apps)); |
| +} |
| + |
| +bool FakeAppInstance::GenerateAndSendIcon(const arc::AppInfo& app, |
| + arc::ScaleFactor scale_factor, |
| + std::string* png_data_as_string) { |
| + CHECK(png_data_as_string != nullptr); |
| + std::string icon_file_name; |
| + switch (scale_factor) { |
| + case arc::SCALE_FACTOR_SCALE_FACTOR_100P: |
| + icon_file_name = "icon_100p.png"; |
| + break; |
| + case arc::SCALE_FACTOR_SCALE_FACTOR_125P: |
| + icon_file_name = "icon_125p.png"; |
| + break; |
| + case arc::SCALE_FACTOR_SCALE_FACTOR_133P: |
| + icon_file_name = "icon_133p.png"; |
| + break; |
| + case arc::SCALE_FACTOR_SCALE_FACTOR_140P: |
| + icon_file_name = "icon_140p.png"; |
| + break; |
| + case arc::SCALE_FACTOR_SCALE_FACTOR_150P: |
| + icon_file_name = "icon_150p.png"; |
| + break; |
| + case arc::SCALE_FACTOR_SCALE_FACTOR_180P: |
| + icon_file_name = "icon_180p.png"; |
| + break; |
| + case arc::SCALE_FACTOR_SCALE_FACTOR_200P: |
| + icon_file_name = "icon_200p.png"; |
| + break; |
| + case arc::SCALE_FACTOR_SCALE_FACTOR_250P: |
| + icon_file_name = "icon_250p.png"; |
| + break; |
| + case arc::SCALE_FACTOR_SCALE_FACTOR_300P: |
| + icon_file_name = "icon_300p.png"; |
| + break; |
| + default: |
| + NOTREACHED(); |
| + return false; |
| + } |
| + |
| + base::FilePath base_path; |
| + CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &base_path)); |
| + base::FilePath icon_file_path = base_path.AppendASCII("components") |
| + .AppendASCII("test") |
| + .AppendASCII("data") |
| + .AppendASCII("arc") |
| + .AppendASCII(icon_file_name); |
| + CHECK(base::PathExists(icon_file_path)); |
| + CHECK(base::ReadFileToString(icon_file_path, png_data_as_string)); |
| + |
| + std::vector<uint8_t> png_data(png_data_as_string->begin(), |
| + png_data_as_string->end()); |
| + |
| + app_host_->OnAppIcon(app.package, app.activity, scale_factor, |
| + mojo::Array<uint8_t>::From(png_data)); |
| + |
| + return true; |
| +} |
| + |
| } // namespace |
| class ArcAppModelBuilderTest : public AppListTestBase { |
| @@ -60,6 +234,11 @@ class ArcAppModelBuilderTest : public AppListTestBase { |
| } |
| bridge_service_.reset(new arc::FakeArcBridgeService()); |
| + app_instance_.reset( |
| + new FakeAppInstance(ArcAppListPrefs::Get(profile_.get()))); |
| + arc::AppInstancePtr instance; |
| + app_instance_->Bind(mojo::GetProxy(&instance)); |
| + bridge_service_->SetAppInstance(std::move(instance)); |
| // Check initial conditions. |
| EXPECT_EQ(bridge_service_.get(), arc::ArcBridgeService::Get()); |
| @@ -189,13 +368,14 @@ class ArcAppModelBuilderTest : public AppListTestBase { |
| ASSERT_NE(nullptr, app_item); |
| EXPECT_NE(ready, app_item->ready()); |
| } |
| - |
| } |
| AppListControllerDelegate* controller() { return controller_.get(); } |
| arc::FakeArcBridgeService* bridge_service() { return bridge_service_.get(); } |
| + FakeAppInstance* app_instance() { return app_instance_.get(); } |
| + |
| const std::vector<arc::AppInfo>& fake_apps() const { return fake_apps_; } |
| private: |
| @@ -203,49 +383,53 @@ class ArcAppModelBuilderTest : public AppListTestBase { |
| scoped_ptr<test::TestAppListControllerDelegate> controller_; |
| scoped_ptr<ArcAppModelBuilder> builder_; |
| scoped_ptr<arc::FakeArcBridgeService> bridge_service_; |
| + scoped_ptr<FakeAppInstance> app_instance_; |
| std::vector<arc::AppInfo> fake_apps_; |
| DISALLOW_COPY_AND_ASSIGN(ArcAppModelBuilderTest); |
| }; |
| TEST_F(ArcAppModelBuilderTest, RefreshAllOnReady) { |
| - EXPECT_EQ(0, bridge_service()->refresh_app_list_count()); |
| + EXPECT_EQ(0, app_instance()->refresh_app_list_count()); |
| bridge_service()->SetReady(); |
| - EXPECT_EQ(1, bridge_service()->refresh_app_list_count()); |
| + app_instance()->RefreshAppList(); |
| + EXPECT_EQ(1, app_instance()->refresh_app_list_count()); |
| } |
| TEST_F(ArcAppModelBuilderTest, RefreshAllFillsContent) { |
| ValidateHaveApps(std::vector<arc::AppInfo>()); |
| bridge_service()->SetReady(); |
| - bridge_service()->SendRefreshAppList(fake_apps()); |
| + app_instance()->RefreshAppList(); |
| + app_instance()->SendRefreshAppList(fake_apps()); |
| ValidateHaveApps(fake_apps()); |
| } |
| TEST_F(ArcAppModelBuilderTest, MultipleRefreshAll) { |
| ValidateHaveApps(std::vector<arc::AppInfo>()); |
| bridge_service()->SetReady(); |
| + app_instance()->RefreshAppList(); |
| // Send info about all fake apps except last. |
| std::vector<arc::AppInfo> apps1(fake_apps().begin(), fake_apps().end() - 1); |
| - bridge_service()->SendRefreshAppList(apps1); |
| + app_instance()->SendRefreshAppList(apps1); |
| // At this point all apps (except last) should exist and be ready. |
| ValidateHaveApps(apps1); |
| ValidateAppReadyState(apps1, true); |
| // Send info about all fake apps except first. |
| std::vector<arc::AppInfo> apps2(fake_apps().begin() + 1, fake_apps().end()); |
| - bridge_service()->SendRefreshAppList(apps2); |
| + app_instance()->SendRefreshAppList(apps2); |
| // At this point all apps should exist but first one should be non-ready. |
| ValidateHaveApps(fake_apps()); |
| ValidateAppReadyState(apps2, true); |
| // Send info about all fake apps. |
| - bridge_service()->SendRefreshAppList(fake_apps()); |
| + app_instance()->SendRefreshAppList(fake_apps()); |
| // At this point all apps should exist and be ready. |
| ValidateHaveApps(fake_apps()); |
| ValidateAppReadyState(fake_apps(), true); |
| // Send info no app available. |
| - bridge_service()->SendRefreshAppList(std::vector<arc::AppInfo>()); |
| + app_instance()->SendRefreshAppList(std::vector<arc::AppInfo>()); |
| // At this point all apps should exist and be non-ready. |
| ValidateHaveApps(fake_apps()); |
| ValidateAppReadyState(fake_apps(), false); |
| @@ -256,10 +440,11 @@ TEST_F(ArcAppModelBuilderTest, StopServiceDisablesApps) { |
| ASSERT_NE(nullptr, prefs); |
| bridge_service()->SetReady(); |
| + app_instance()->RefreshAppList(); |
| EXPECT_EQ(static_cast<size_t>(0), GetArcItemCount()); |
| EXPECT_EQ(static_cast<size_t>(0), prefs->GetAppIds().size()); |
| - bridge_service()->SendRefreshAppList(fake_apps()); |
| + app_instance()->SendRefreshAppList(fake_apps()); |
| std::vector<std::string> ids = prefs->GetAppIds(); |
| EXPECT_EQ(fake_apps().size(), ids.size()); |
| ValidateAppReadyState(fake_apps(), true); |
| @@ -276,7 +461,8 @@ TEST_F(ArcAppModelBuilderTest, LaunchApps) { |
| ChromeAppListItem::OverrideAppListControllerDelegateForTesting(controller()); |
| bridge_service()->SetReady(); |
| - bridge_service()->SendRefreshAppList(fake_apps()); |
| + app_instance()->RefreshAppList(); |
| + app_instance()->SendRefreshAppList(fake_apps()); |
| // Simulate item activate. |
| const arc::AppInfo& app_first = fake_apps()[0]; |
| @@ -289,23 +475,25 @@ TEST_F(ArcAppModelBuilderTest, LaunchApps) { |
| item_last->Activate(0); |
| item_first->Activate(0); |
| - const ScopedVector<arc::FakeArcBridgeService::Request>& launch_requests = |
| - bridge_service()->launch_requests(); |
| - EXPECT_EQ(static_cast<size_t>(3), launch_requests.size()); |
| + // Process pending tasks. |
| + base::RunLoop().RunUntilIdle(); |
| + |
| + const ScopedVector<FakeAppInstance::Request>& launch_requests = |
| + app_instance()->launch_requests(); |
| + ASSERT_EQ(static_cast<size_t>(3), launch_requests.size()); |
| EXPECT_EQ(true, launch_requests[0]->IsForApp(app_first)); |
| EXPECT_EQ(true, launch_requests[1]->IsForApp(app_last)); |
| EXPECT_EQ(true, launch_requests[2]->IsForApp(app_first)); |
| // Test an attempt to launch of a not-ready app. |
| - bridge_service()->SendRefreshAppList(std::vector<arc::AppInfo>()); |
| + app_instance()->SendRefreshAppList(std::vector<arc::AppInfo>()); |
| item_first = FindArcItem(GetAppId(app_first)); |
| ASSERT_NE(nullptr, item_first); |
| - size_t launch_request_count_before = |
| - bridge_service()->launch_requests().size(); |
| + size_t launch_request_count_before = app_instance()->launch_requests().size(); |
| item_first->Activate(0); |
| // Number of launch requests must not change. |
| EXPECT_EQ(launch_request_count_before, |
| - bridge_service()->launch_requests().size()); |
| + app_instance()->launch_requests().size()); |
| } |
| TEST_F(ArcAppModelBuilderTest, RequestIcons) { |
| @@ -314,7 +502,8 @@ TEST_F(ArcAppModelBuilderTest, RequestIcons) { |
| content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| bridge_service()->SetReady(); |
| - bridge_service()->SendRefreshAppList(fake_apps()); |
| + app_instance()->RefreshAppList(); |
| + app_instance()->SendRefreshAppList(fake_apps()); |
| // Validate that no icon exists at the beginning and request icon for |
| // each supported scale factor. This will start asynchronous loading. |
| @@ -336,13 +525,12 @@ TEST_F(ArcAppModelBuilderTest, RequestIcons) { |
| base::RunLoop().RunUntilIdle(); |
| // At this moment we should receive all requests for icon loading. |
| - const ScopedVector<arc::FakeArcBridgeService::IconRequest>& icon_requests = |
| - bridge_service()->icon_requests(); |
| + const ScopedVector<FakeAppInstance::IconRequest>& icon_requests = |
| + app_instance()->icon_requests(); |
| EXPECT_EQ(scale_factors.size() * fake_apps().size(), icon_requests.size()); |
| std::map<std::string, uint32_t> app_masks; |
| for (size_t i = 0; i < icon_requests.size(); ++i) { |
| - const arc::FakeArcBridgeService::IconRequest* icon_request = |
| - icon_requests[i]; |
| + const FakeAppInstance::IconRequest* icon_request = icon_requests[i]; |
| const std::string id = ArcAppListPrefs::GetAppId(icon_request->package(), |
| icon_request->activity()); |
| // Make sure no double requests. |
| @@ -368,8 +556,9 @@ TEST_F(ArcAppModelBuilderTest, InstallIcon) { |
| bridge_service()->SetReady(); |
| - bridge_service()->SendRefreshAppList(std::vector<arc::AppInfo>( |
| - fake_apps().begin(), fake_apps().begin() + 1)); |
| + app_instance()->RefreshAppList(); |
| + app_instance()->SendRefreshAppList( |
| + std::vector<arc::AppInfo>(fake_apps().begin(), fake_apps().begin() + 1)); |
| const arc::AppInfo& app = fake_apps()[0]; |
| ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_.get()); |
| @@ -395,10 +584,9 @@ TEST_F(ArcAppModelBuilderTest, InstallIcon) { |
| // Now send generated icon for the app. |
| std::string png_data; |
| - EXPECT_EQ(true, bridge_service()->GenerateAndSendIcon( |
| - app, |
| - static_cast<arc::ScaleFactor>(scale_factor), |
| - &png_data)); |
| + EXPECT_EQ(true, |
| + app_instance()->GenerateAndSendIcon( |
| + app, static_cast<arc::ScaleFactor>(scale_factor), &png_data)); |
| // Process pending tasks. |
| content::BrowserThread::GetBlockingPool()->FlushForTesting(); |