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(); |