| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <map> | 9 #include <map> |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 #include "chrome/browser/ui/app_list/arc/arc_default_app_list.h" | 36 #include "chrome/browser/ui/app_list/arc/arc_default_app_list.h" |
| 37 #include "chrome/browser/ui/app_list/arc/arc_package_syncable_service_factory.h" | 37 #include "chrome/browser/ui/app_list/arc/arc_package_syncable_service_factory.h" |
| 38 #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h" | 38 #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h" |
| 39 #include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h" | 39 #include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h" |
| 40 #include "chrome/common/pref_names.h" | 40 #include "chrome/common/pref_names.h" |
| 41 #include "chrome/test/base/testing_profile.h" | 41 #include "chrome/test/base/testing_profile.h" |
| 42 #include "components/arc/arc_util.h" | 42 #include "components/arc/arc_util.h" |
| 43 #include "components/arc/test/fake_app_instance.h" | 43 #include "components/arc/test/fake_app_instance.h" |
| 44 #include "components/sync_preferences/testing_pref_service_syncable.h" | 44 #include "components/sync_preferences/testing_pref_service_syncable.h" |
| 45 #include "content/public/browser/browser_thread.h" | 45 #include "content/public/browser/browser_thread.h" |
| 46 #include "content/public/test/test_utils.h" |
| 46 #include "extensions/browser/extension_system.h" | 47 #include "extensions/browser/extension_system.h" |
| 47 #include "extensions/common/extension.h" | 48 #include "extensions/common/extension.h" |
| 48 #include "extensions/common/manifest_constants.h" | 49 #include "extensions/common/manifest_constants.h" |
| 49 #include "testing/gtest/include/gtest/gtest.h" | 50 #include "testing/gtest/include/gtest/gtest.h" |
| 50 #include "ui/app_list/app_list_constants.h" | 51 #include "ui/app_list/app_list_constants.h" |
| 51 #include "ui/app_list/app_list_model.h" | 52 #include "ui/app_list/app_list_model.h" |
| 52 #include "ui/events/event_constants.h" | 53 #include "ui/events/event_constants.h" |
| 53 #include "ui/gfx/geometry/safe_integer_conversions.h" | 54 #include "ui/gfx/geometry/safe_integer_conversions.h" |
| 54 #include "ui/gfx/image/image_skia.h" | 55 #include "ui/gfx/image/image_skia.h" |
| 55 | 56 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 83 DISALLOW_COPY_AND_ASSIGN(FakeAppIconLoaderDelegate); | 84 DISALLOW_COPY_AND_ASSIGN(FakeAppIconLoaderDelegate); |
| 84 }; | 85 }; |
| 85 | 86 |
| 86 void WaitForIconReady(ArcAppListPrefs* prefs, | 87 void WaitForIconReady(ArcAppListPrefs* prefs, |
| 87 const std::string& app_id, | 88 const std::string& app_id, |
| 88 ui::ScaleFactor scale_factor) { | 89 ui::ScaleFactor scale_factor) { |
| 89 const base::FilePath icon_path = prefs->GetIconPath(app_id, scale_factor); | 90 const base::FilePath icon_path = prefs->GetIconPath(app_id, scale_factor); |
| 90 // Process pending tasks. This performs multiple thread hops, so we need | 91 // Process pending tasks. This performs multiple thread hops, so we need |
| 91 // to run it continuously until it is resolved. | 92 // to run it continuously until it is resolved. |
| 92 do { | 93 do { |
| 93 content::BrowserThread::GetBlockingPool()->FlushForTesting(); | 94 content::RunAllBlockingPoolTasksUntilIdle(); |
| 94 base::RunLoop().RunUntilIdle(); | |
| 95 } while (!base::PathExists(icon_path)); | 95 } while (!base::PathExists(icon_path)); |
| 96 } | 96 } |
| 97 | 97 |
| 98 enum class ArcState { | 98 enum class ArcState { |
| 99 // By default, ARC is non-persistent and Play Store is unmanaged. | 99 // By default, ARC is non-persistent and Play Store is unmanaged. |
| 100 ARC_PLAY_STORE_UNMANAGED, | 100 ARC_PLAY_STORE_UNMANAGED, |
| 101 // ARC is persistent and Play Store is unmanaged | 101 // ARC is persistent and Play Store is unmanaged |
| 102 ARC_PERSISTENT_PLAY_STORE_UNMANAGED, | 102 ARC_PERSISTENT_PLAY_STORE_UNMANAGED, |
| 103 // ARC is non-persistent and Play Store is managed and enabled. | 103 // ARC is non-persistent and Play Store is managed and enabled. |
| 104 ARC_PLAY_STORE_MANAGED_AND_ENABLED, | 104 ARC_PLAY_STORE_MANAGED_AND_ENABLED, |
| (...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 811 for (auto& scale_factor : scale_factors) { | 811 for (auto& scale_factor : scale_factors) { |
| 812 expected_mask |= 1 << scale_factor; | 812 expected_mask |= 1 << scale_factor; |
| 813 for (auto& app : fake_apps()) { | 813 for (auto& app : fake_apps()) { |
| 814 ArcAppItem* app_item = FindArcItem(ArcAppTest::GetAppId(app)); | 814 ArcAppItem* app_item = FindArcItem(ArcAppTest::GetAppId(app)); |
| 815 ASSERT_NE(nullptr, app_item); | 815 ASSERT_NE(nullptr, app_item); |
| 816 const float scale = ui::GetScaleForScaleFactor(scale_factor); | 816 const float scale = ui::GetScaleForScaleFactor(scale_factor); |
| 817 app_item->icon().GetRepresentation(scale); | 817 app_item->icon().GetRepresentation(scale); |
| 818 | 818 |
| 819 // This does not result in an icon being loaded, so WaitForIconReady | 819 // This does not result in an icon being loaded, so WaitForIconReady |
| 820 // cannot be used. | 820 // cannot be used. |
| 821 content::BrowserThread::GetBlockingPool()->FlushForTesting(); | 821 content::RunAllBlockingPoolTasksUntilIdle(); |
| 822 base::RunLoop().RunUntilIdle(); | |
| 823 } | 822 } |
| 824 } | 823 } |
| 825 | 824 |
| 826 const size_t expected_size = scale_factors.size() * fake_apps().size(); | 825 const size_t expected_size = scale_factors.size() * fake_apps().size(); |
| 827 | 826 |
| 828 // At this moment we should receive all requests for icon loading. | 827 // At this moment we should receive all requests for icon loading. |
| 829 const std::vector<std::unique_ptr<arc::FakeAppInstance::IconRequest>>& | 828 const std::vector<std::unique_ptr<arc::FakeAppInstance::IconRequest>>& |
| 830 icon_requests = app_instance()->icon_requests(); | 829 icon_requests = app_instance()->icon_requests(); |
| 831 EXPECT_EQ(expected_size, icon_requests.size()); | 830 EXPECT_EQ(expected_size, icon_requests.size()); |
| 832 std::map<std::string, uint32_t> app_masks; | 831 std::map<std::string, uint32_t> app_masks; |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 970 WaitForIconReady(prefs, app_id, scale_factor); | 969 WaitForIconReady(prefs, app_id, scale_factor); |
| 971 EXPECT_TRUE(base::PathExists(app_path)); | 970 EXPECT_TRUE(base::PathExists(app_path)); |
| 972 | 971 |
| 973 // Send empty app list. This will delete app and its folder. | 972 // Send empty app list. This will delete app and its folder. |
| 974 app_instance()->SendRefreshAppList(std::vector<arc::mojom::AppInfo>()); | 973 app_instance()->SendRefreshAppList(std::vector<arc::mojom::AppInfo>()); |
| 975 // This cannot be WaitForIconReady since it needs to wait until the icon is | 974 // This cannot be WaitForIconReady since it needs to wait until the icon is |
| 976 // removed, not added. | 975 // removed, not added. |
| 977 // Process pending tasks. This performs multiple thread hops, so we need | 976 // Process pending tasks. This performs multiple thread hops, so we need |
| 978 // to run it continuously until it is resolved. | 977 // to run it continuously until it is resolved. |
| 979 do { | 978 do { |
| 980 content::BrowserThread::GetBlockingPool()->FlushForTesting(); | 979 content::RunAllBlockingPoolTasksUntilIdle(); |
| 981 base::RunLoop().RunUntilIdle(); | |
| 982 } while (base::PathExists(app_path)); | 980 } while (base::PathExists(app_path)); |
| 983 EXPECT_FALSE(base::PathExists(app_path)); | 981 EXPECT_FALSE(base::PathExists(app_path)); |
| 984 } | 982 } |
| 985 | 983 |
| 986 TEST_P(ArcAppModelBuilderTest, LastLaunchTime) { | 984 TEST_P(ArcAppModelBuilderTest, LastLaunchTime) { |
| 987 // Make sure we are on UI thread. | 985 // Make sure we are on UI thread. |
| 988 ASSERT_TRUE(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 986 ASSERT_TRUE(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 989 | 987 |
| 990 app_instance()->RefreshAppList(); | 988 app_instance()->RefreshAppList(); |
| 991 app_instance()->SendRefreshAppList(std::vector<arc::mojom::AppInfo>( | 989 app_instance()->SendRefreshAppList(std::vector<arc::mojom::AppInfo>( |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1105 TEST_P(ArcAppModelBuilderTest, IconLoaderForShelfGroup) { | 1103 TEST_P(ArcAppModelBuilderTest, IconLoaderForShelfGroup) { |
| 1106 const arc::mojom::AppInfo& app = fake_apps()[0]; | 1104 const arc::mojom::AppInfo& app = fake_apps()[0]; |
| 1107 const std::string app_id = ArcAppTest::GetAppId(app); | 1105 const std::string app_id = ArcAppTest::GetAppId(app); |
| 1108 | 1106 |
| 1109 ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_.get()); | 1107 ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_.get()); |
| 1110 ASSERT_NE(nullptr, prefs); | 1108 ASSERT_NE(nullptr, prefs); |
| 1111 | 1109 |
| 1112 app_instance()->RefreshAppList(); | 1110 app_instance()->RefreshAppList(); |
| 1113 app_instance()->SendRefreshAppList(std::vector<arc::mojom::AppInfo>( | 1111 app_instance()->SendRefreshAppList(std::vector<arc::mojom::AppInfo>( |
| 1114 fake_apps().begin(), fake_apps().begin() + 1)); | 1112 fake_apps().begin(), fake_apps().begin() + 1)); |
| 1115 content::BrowserThread::GetBlockingPool()->FlushForTesting(); | 1113 content::RunAllBlockingPoolTasksUntilIdle(); |
| 1116 base::RunLoop().RunUntilIdle(); | |
| 1117 | 1114 |
| 1118 // Store number of requests generated during the App List item creation. Same | 1115 // Store number of requests generated during the App List item creation. Same |
| 1119 // request will not be re-sent without clearing the request record in | 1116 // request will not be re-sent without clearing the request record in |
| 1120 // ArcAppListPrefs. | 1117 // ArcAppListPrefs. |
| 1121 const size_t initial_icon_request_count = | 1118 const size_t initial_icon_request_count = |
| 1122 app_instance()->icon_requests().size(); | 1119 app_instance()->icon_requests().size(); |
| 1123 | 1120 |
| 1124 std::vector<arc::mojom::ShortcutInfo> shortcuts = | 1121 std::vector<arc::mojom::ShortcutInfo> shortcuts = |
| 1125 arc_test()->fake_shortcuts(); | 1122 arc_test()->fake_shortcuts(); |
| 1126 shortcuts.resize(1); | 1123 shortcuts.resize(1); |
| 1127 shortcuts[0].intent_uri += | 1124 shortcuts[0].intent_uri += |
| 1128 ";S.org.chromium.arc.shelf_group_id=arc_test_shelf_group;end"; | 1125 ";S.org.chromium.arc.shelf_group_id=arc_test_shelf_group;end"; |
| 1129 app_instance()->SendInstallShortcuts(shortcuts); | 1126 app_instance()->SendInstallShortcuts(shortcuts); |
| 1130 const std::string shortcut_id = ArcAppTest::GetAppId(shortcuts[0]); | 1127 const std::string shortcut_id = ArcAppTest::GetAppId(shortcuts[0]); |
| 1131 content::BrowserThread::GetBlockingPool()->FlushForTesting(); | 1128 content::RunAllBlockingPoolTasksUntilIdle(); |
| 1132 base::RunLoop().RunUntilIdle(); | |
| 1133 | 1129 |
| 1134 const std::string id_shortcut_exist = | 1130 const std::string id_shortcut_exist = |
| 1135 arc::ArcAppShelfId("arc_test_shelf_group", app_id).ToString(); | 1131 arc::ArcAppShelfId("arc_test_shelf_group", app_id).ToString(); |
| 1136 const std::string id_shortcut_absent = | 1132 const std::string id_shortcut_absent = |
| 1137 arc::ArcAppShelfId("arc_test_shelf_group_absent", app_id).ToString(); | 1133 arc::ArcAppShelfId("arc_test_shelf_group_absent", app_id).ToString(); |
| 1138 | 1134 |
| 1139 FakeAppIconLoaderDelegate delegate; | 1135 FakeAppIconLoaderDelegate delegate; |
| 1140 ArcAppIconLoader icon_loader(profile(), app_list::kListIconSize, &delegate); | 1136 ArcAppIconLoader icon_loader(profile(), app_list::kListIconSize, &delegate); |
| 1141 EXPECT_EQ(0UL, delegate.update_image_cnt()); | 1137 EXPECT_EQ(0UL, delegate.update_image_cnt()); |
| 1142 | 1138 |
| 1143 // Shortcut exists, icon is requested from shortcut. | 1139 // Shortcut exists, icon is requested from shortcut. |
| 1144 icon_loader.FetchImage(id_shortcut_exist); | 1140 icon_loader.FetchImage(id_shortcut_exist); |
| 1145 EXPECT_EQ(1UL, delegate.update_image_cnt()); | 1141 EXPECT_EQ(1UL, delegate.update_image_cnt()); |
| 1146 EXPECT_EQ(id_shortcut_exist, delegate.app_id()); | 1142 EXPECT_EQ(id_shortcut_exist, delegate.app_id()); |
| 1147 content::BrowserThread::GetBlockingPool()->FlushForTesting(); | 1143 content::RunAllBlockingPoolTasksUntilIdle(); |
| 1148 base::RunLoop().RunUntilIdle(); | |
| 1149 const size_t shortcut_request_cnt = | 1144 const size_t shortcut_request_cnt = |
| 1150 app_instance()->shortcut_icon_requests().size(); | 1145 app_instance()->shortcut_icon_requests().size(); |
| 1151 EXPECT_NE(0U, shortcut_request_cnt); | 1146 EXPECT_NE(0U, shortcut_request_cnt); |
| 1152 EXPECT_EQ(initial_icon_request_count, app_instance()->icon_requests().size()); | 1147 EXPECT_EQ(initial_icon_request_count, app_instance()->icon_requests().size()); |
| 1153 for (const auto& request : app_instance()->shortcut_icon_requests()) { | 1148 for (const auto& request : app_instance()->shortcut_icon_requests()) { |
| 1154 EXPECT_EQ(shortcuts[0].icon_resource_id, request->icon_resource_id()); | 1149 EXPECT_EQ(shortcuts[0].icon_resource_id, request->icon_resource_id()); |
| 1155 } | 1150 } |
| 1156 | 1151 |
| 1157 // Fallback when shortcut is not found for shelf group id, use app id instead. | 1152 // Fallback when shortcut is not found for shelf group id, use app id instead. |
| 1158 // Remove the IconRequestRecord for |app_id| to observe the icon request for | 1153 // Remove the IconRequestRecord for |app_id| to observe the icon request for |
| 1159 // |app_id| is re-sent. | 1154 // |app_id| is re-sent. |
| 1160 MaybeRemoveIconRequestRecord(app_id); | 1155 MaybeRemoveIconRequestRecord(app_id); |
| 1161 icon_loader.FetchImage(id_shortcut_absent); | 1156 icon_loader.FetchImage(id_shortcut_absent); |
| 1162 EXPECT_EQ(2UL, delegate.update_image_cnt()); | 1157 EXPECT_EQ(2UL, delegate.update_image_cnt()); |
| 1163 content::BrowserThread::GetBlockingPool()->FlushForTesting(); | 1158 content::RunAllBlockingPoolTasksUntilIdle(); |
| 1164 base::RunLoop().RunUntilIdle(); | |
| 1165 EXPECT_TRUE(app_instance()->icon_requests().size() > | 1159 EXPECT_TRUE(app_instance()->icon_requests().size() > |
| 1166 initial_icon_request_count); | 1160 initial_icon_request_count); |
| 1167 EXPECT_EQ(shortcut_request_cnt, | 1161 EXPECT_EQ(shortcut_request_cnt, |
| 1168 app_instance()->shortcut_icon_requests().size()); | 1162 app_instance()->shortcut_icon_requests().size()); |
| 1169 for (size_t i = initial_icon_request_count; | 1163 for (size_t i = initial_icon_request_count; |
| 1170 i < app_instance()->icon_requests().size(); ++i) { | 1164 i < app_instance()->icon_requests().size(); ++i) { |
| 1171 const auto& request = app_instance()->icon_requests()[i]; | 1165 const auto& request = app_instance()->icon_requests()[i]; |
| 1172 EXPECT_TRUE(request->IsForApp(app)); | 1166 EXPECT_TRUE(request->IsForApp(app)); |
| 1173 } | 1167 } |
| 1174 } | 1168 } |
| 1175 | 1169 |
| 1176 // If the cached icon file is corrupted, we expect send request to ARC for a new | 1170 // If the cached icon file is corrupted, we expect send request to ARC for a new |
| 1177 // icon. | 1171 // icon. |
| 1178 TEST_P(ArcAppModelBuilderTest, IconLoaderWithBadIcon) { | 1172 TEST_P(ArcAppModelBuilderTest, IconLoaderWithBadIcon) { |
| 1179 const arc::mojom::AppInfo& app = fake_apps()[0]; | 1173 const arc::mojom::AppInfo& app = fake_apps()[0]; |
| 1180 const std::string app_id = ArcAppTest::GetAppId(app); | 1174 const std::string app_id = ArcAppTest::GetAppId(app); |
| 1181 | 1175 |
| 1182 ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_.get()); | 1176 ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_.get()); |
| 1183 ASSERT_NE(nullptr, prefs); | 1177 ASSERT_NE(nullptr, prefs); |
| 1184 | 1178 |
| 1185 app_instance()->RefreshAppList(); | 1179 app_instance()->RefreshAppList(); |
| 1186 app_instance()->SendRefreshAppList(std::vector<arc::mojom::AppInfo>( | 1180 app_instance()->SendRefreshAppList(std::vector<arc::mojom::AppInfo>( |
| 1187 fake_apps().begin(), fake_apps().begin() + 1)); | 1181 fake_apps().begin(), fake_apps().begin() + 1)); |
| 1188 content::BrowserThread::GetBlockingPool()->FlushForTesting(); | 1182 content::RunAllBlockingPoolTasksUntilIdle(); |
| 1189 base::RunLoop().RunUntilIdle(); | |
| 1190 | 1183 |
| 1191 // Store number of requests generated during the App List item creation. Same | 1184 // Store number of requests generated during the App List item creation. Same |
| 1192 // request will not be re-sent without clearing the request record in | 1185 // request will not be re-sent without clearing the request record in |
| 1193 // ArcAppListPrefs. | 1186 // ArcAppListPrefs. |
| 1194 const size_t initial_icon_request_count = | 1187 const size_t initial_icon_request_count = |
| 1195 app_instance()->icon_requests().size(); | 1188 app_instance()->icon_requests().size(); |
| 1196 | 1189 |
| 1197 FakeAppIconLoaderDelegate delegate; | 1190 FakeAppIconLoaderDelegate delegate; |
| 1198 ArcAppIconLoader icon_loader(profile(), app_list::kListIconSize, &delegate); | 1191 ArcAppIconLoader icon_loader(profile(), app_list::kListIconSize, &delegate); |
| 1199 icon_loader.FetchImage(app_id); | 1192 icon_loader.FetchImage(app_id); |
| 1200 | 1193 |
| 1201 content::BrowserThread::GetBlockingPool()->FlushForTesting(); | 1194 content::RunAllBlockingPoolTasksUntilIdle(); |
| 1202 base::RunLoop().RunUntilIdle(); | |
| 1203 // Although icon file is still missing, expect no new request sent to ARC as | 1195 // Although icon file is still missing, expect no new request sent to ARC as |
| 1204 // them are recorded in IconRequestRecord in ArcAppListPrefs. | 1196 // them are recorded in IconRequestRecord in ArcAppListPrefs. |
| 1205 EXPECT_EQ(app_instance()->icon_requests().size(), initial_icon_request_count); | 1197 EXPECT_EQ(app_instance()->icon_requests().size(), initial_icon_request_count); |
| 1206 // Validate default image. | 1198 // Validate default image. |
| 1207 ValidateIcon(delegate.image()); | 1199 ValidateIcon(delegate.image()); |
| 1208 | 1200 |
| 1209 MaybeRemoveIconRequestRecord(app_id); | 1201 MaybeRemoveIconRequestRecord(app_id); |
| 1210 | 1202 |
| 1211 // Install Bad image. | 1203 // Install Bad image. |
| 1212 const std::vector<ui::ScaleFactor>& scale_factors = | 1204 const std::vector<ui::ScaleFactor>& scale_factors = |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1580 ::testing::ValuesIn(kUnmanagedArcStates)); | 1572 ::testing::ValuesIn(kUnmanagedArcStates)); |
| 1581 INSTANTIATE_TEST_CASE_P(, | 1573 INSTANTIATE_TEST_CASE_P(, |
| 1582 ArcDefaulAppForManagedUserTest, | 1574 ArcDefaulAppForManagedUserTest, |
| 1583 ::testing::ValuesIn(kManagedArcStates)); | 1575 ::testing::ValuesIn(kManagedArcStates)); |
| 1584 INSTANTIATE_TEST_CASE_P(, | 1576 INSTANTIATE_TEST_CASE_P(, |
| 1585 ArcPlayStoreAppTest, | 1577 ArcPlayStoreAppTest, |
| 1586 ::testing::ValuesIn(kUnmanagedArcStates)); | 1578 ::testing::ValuesIn(kUnmanagedArcStates)); |
| 1587 INSTANTIATE_TEST_CASE_P(, | 1579 INSTANTIATE_TEST_CASE_P(, |
| 1588 ArcAppModelBuilderRecreate, | 1580 ArcAppModelBuilderRecreate, |
| 1589 ::testing::ValuesIn(kUnmanagedArcStates)); | 1581 ::testing::ValuesIn(kUnmanagedArcStates)); |
| OLD | NEW |