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

Side by Side Diff: chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views_unittest.cc

Issue 2700523002: arc: Fix crash on accessing app info for secondary user. (Closed)
Patch Set: minor comment update Created 3 years, 10 months 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 unified diff | Download patch
« no previous file with comments | « chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.h" 5 #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <string> 8 #include <string>
9 9
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "base/run_loop.h" 12 #include "base/run_loop.h"
13 #include "chrome/browser/extensions/extension_service.h" 13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/test_extension_environment.h" 14 #include "chrome/browser/extensions/test_extension_environment.h"
15 #include "chrome/browser/ui/tabs/tab_strip_model.h" 15 #include "chrome/browser/ui/tabs/tab_strip_model.h"
16 #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.h" 16 #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.h"
17 #include "chrome/common/extensions/extension_constants.h"
17 #include "chrome/test/base/browser_with_test_window_test.h" 18 #include "chrome/test/base/browser_with_test_window_test.h"
18 #include "chrome/test/base/testing_profile.h" 19 #include "chrome/test/base/testing_profile.h"
19 #include "extensions/browser/extension_system.h" 20 #include "extensions/browser/extension_system.h"
20 #include "testing/gtest/include/gtest/gtest.h" 21 #include "testing/gtest/include/gtest/gtest.h"
21 #include "ui/views/controls/link.h" 22 #include "ui/views/controls/link.h"
22 #include "ui/views/test/scoped_views_test_helper.h" 23 #include "ui/views/test/scoped_views_test_helper.h"
23 #include "ui/views/widget/widget.h" 24 #include "ui/views/widget/widget.h"
24 #include "ui/views/widget/widget_observer.h" 25 #include "ui/views/widget/widget_observer.h"
25 #include "ui/views/window/dialog_delegate.h" 26 #include "ui/views/window/dialog_delegate.h"
26 27
27 #if defined(OS_CHROMEOS) 28 #if defined(OS_CHROMEOS)
28 #include "chrome/browser/chromeos/arc/arc_session_manager.h" 29 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
29 #include "components/arc/arc_session_runner.h" 30 #include "chrome/browser/ui/app_list/arc/arc_app_test.h"
30 #include "components/arc/test/fake_arc_session.h" 31 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
32 #endif
33
34 #if defined(OS_CHROMEOS)
35 namespace {
36
37 std::vector<arc::mojom::AppInfoPtr> GetArcSettingsAppInfo() {
38 std::vector<arc::mojom::AppInfoPtr> apps;
39 arc::mojom::AppInfoPtr app(arc::mojom::AppInfo::New());
40 app->name = "settings";
41 app->package_name = "com.android.settings";
42 app->activity = "com.android.settings.Settings";
43 app->sticky = false;
44 apps.push_back(std::move(app));
45 return apps;
46 }
47
48 } // namespace
31 #endif 49 #endif
32 50
33 namespace test { 51 namespace test {
34 52
35 class AppInfoDialogTestApi { 53 class AppInfoDialogTestApi {
36 public: 54 public:
37 explicit AppInfoDialogTestApi(AppInfoDialog* dialog) : dialog_(dialog) {} 55 explicit AppInfoDialogTestApi(AppInfoDialog* dialog) : dialog_(dialog) {}
38 56
39 AppInfoHeaderPanel* header_panel() { 57 AppInfoHeaderPanel* header_panel() {
40 return static_cast<AppInfoHeaderPanel*>(dialog_->child_at(0)); 58 return static_cast<AppInfoHeaderPanel*>(dialog_->child_at(0));
(...skipping 21 matching lines...) Expand all
62 class AppInfoDialogViewsTest : public BrowserWithTestWindowTest, 80 class AppInfoDialogViewsTest : public BrowserWithTestWindowTest,
63 public views::WidgetObserver { 81 public views::WidgetObserver {
64 public: 82 public:
65 AppInfoDialogViewsTest() 83 AppInfoDialogViewsTest()
66 : extension_environment_(base::MessageLoopForUI::current()) {} 84 : extension_environment_(base::MessageLoopForUI::current()) {}
67 85
68 // Overridden from testing::Test: 86 // Overridden from testing::Test:
69 void SetUp() override { 87 void SetUp() override {
70 BrowserWithTestWindowTest::SetUp(); 88 BrowserWithTestWindowTest::SetUp();
71 #if defined(OS_CHROMEOS) 89 #if defined(OS_CHROMEOS)
72 arc::ArcSessionManager::DisableUIForTesting(); 90 arc_test_.SetUp(extension_environment_.profile());
73 arc_session_manager_ = base::MakeUnique<arc::ArcSessionManager>(
74 base::MakeUnique<arc::ArcSessionRunner>(
75 base::Bind(arc::FakeArcSession::Create)));
76 arc_session_manager_->OnPrimaryUserProfilePrepared(
77 extension_environment_.profile());
78 #endif 91 #endif
79 widget_ = views::DialogDelegate::CreateDialogWidget(
80 new views::DialogDelegateView(), GetContext(), nullptr);
81 widget_->AddObserver(this);
82 extension_ = extension_environment_.MakePackagedApp(kTestExtensionId, true); 92 extension_ = extension_environment_.MakePackagedApp(kTestExtensionId, true);
83 dialog_ = new AppInfoDialog(widget_->GetNativeWindow(), 93 chrome_app_ = extension_environment_.MakePackagedApp(
84 extension_environment_.profile(), 94 extension_misc::kChromeAppId, true);
85 extension_.get());
86
87 widget_->GetContentsView()->AddChildView(dialog_);
88 widget_->Show();
89 } 95 }
90 96
91 void TearDown() override { 97 void TearDown() override {
92 if (!widget_destroyed_) 98 CloseAppInfo();
93 widget_->CloseNow();
94 EXPECT_TRUE(widget_destroyed_);
95 extension_ = nullptr; 99 extension_ = nullptr;
100 chrome_app_ = nullptr;
96 #if defined(OS_CHROMEOS) 101 #if defined(OS_CHROMEOS)
97 if (arc_session_manager_) { 102 arc_test_.TearDown();
98 arc_session_manager_->Shutdown();
99 arc_session_manager_ = nullptr;
100 }
101 #endif 103 #endif
102 BrowserWithTestWindowTest::TearDown(); 104 BrowserWithTestWindowTest::TearDown();
103 } 105 }
104 106
105 // BrowserWithTestWindowTest: 107 // BrowserWithTestWindowTest:
106 TestingProfile* CreateProfile() override { 108 TestingProfile* CreateProfile() override {
107 return extension_environment_.profile(); 109 return extension_environment_.profile();
108 } 110 }
109 111
110 void DestroyProfile(TestingProfile* profile) override { 112 void DestroyProfile(TestingProfile* profile) override {
111 #if defined(OS_CHROMEOS) 113 #if defined(OS_CHROMEOS)
112 if (arc_session_manager_) { 114 arc_test_.TearDown();
113 arc_session_manager_->Shutdown();
114 arc_session_manager_ = nullptr;
115 }
116 #endif 115 #endif
117 } 116 }
118 117
119 protected: 118 protected:
119 void ShowAppInfo(const std::string& app_id) {
120 ShowAppInfoForProfile(app_id, extension_environment_.profile());
121 }
122
123 void ShowAppInfoForProfile(const std::string& app_id, Profile* profile) {
124 const extensions::Extension* extension =
125 extensions::ExtensionSystem::Get(profile)
126 ->extension_service()
127 ->GetExtensionById(app_id, true);
128 DCHECK(extension);
129
130 DCHECK(!widget_);
131 widget_ = views::DialogDelegate::CreateDialogWidget(
132 new views::DialogDelegateView(), GetContext(), nullptr);
133 widget_->AddObserver(this);
134 dialog_ = new AppInfoDialog(widget_->GetNativeWindow(), profile, extension);
135
136 widget_->GetContentsView()->AddChildView(dialog_);
137 widget_->Show();
138 }
139
140 void CloseAppInfo() {
141 if (widget_)
142 widget_->CloseNow();
143 base::RunLoop().RunUntilIdle();
144 DCHECK(!widget_);
145 }
146
120 // Overridden from views::WidgetObserver: 147 // Overridden from views::WidgetObserver:
121 void OnWidgetDestroyed(views::Widget* widget) override { 148 void OnWidgetDestroyed(views::Widget* widget) override {
122 widget_destroyed_ = true;
123 widget_->RemoveObserver(this); 149 widget_->RemoveObserver(this);
124 widget_ = NULL; 150 widget_ = NULL;
125 } 151 }
126 152
127 void UninstallApp(const std::string& app_id) { 153 void UninstallApp(const std::string& app_id) {
128 extensions::ExtensionSystem::Get(extension_environment_.profile()) 154 extensions::ExtensionSystem::Get(extension_environment_.profile())
129 ->extension_service() 155 ->extension_service()
130 ->UninstallExtension( 156 ->UninstallExtension(
131 app_id, extensions::UninstallReason::UNINSTALL_REASON_FOR_TESTING, 157 app_id, extensions::UninstallReason::UNINSTALL_REASON_FOR_TESTING,
132 base::Closure(), NULL); 158 base::Closure(), NULL);
133 } 159 }
134 160
135 protected: 161 protected:
136 views::Widget* widget_ = nullptr; 162 views::Widget* widget_ = nullptr;
137 bool widget_destroyed_ = false;
138 AppInfoDialog* dialog_ = nullptr; // Owned by |widget_|'s views hierarchy. 163 AppInfoDialog* dialog_ = nullptr; // Owned by |widget_|'s views hierarchy.
139 scoped_refptr<extensions::Extension> extension_; 164 scoped_refptr<extensions::Extension> extension_;
165 scoped_refptr<extensions::Extension> chrome_app_;
140 extensions::TestExtensionEnvironment extension_environment_; 166 extensions::TestExtensionEnvironment extension_environment_;
141 #if defined(OS_CHROMEOS) 167 #if defined(OS_CHROMEOS)
142 std::unique_ptr<arc::ArcSessionManager> arc_session_manager_; 168 ArcAppTest arc_test_;
143 #endif 169 #endif
144 170
145 private: 171 private:
146 DISALLOW_COPY_AND_ASSIGN(AppInfoDialogViewsTest); 172 DISALLOW_COPY_AND_ASSIGN(AppInfoDialogViewsTest);
147 }; 173 };
148 174
149 // Tests that the dialog closes when the current app is uninstalled. 175 // Tests that the dialog closes when the current app is uninstalled.
150 TEST_F(AppInfoDialogViewsTest, UninstallingAppClosesDialog) { 176 TEST_F(AppInfoDialogViewsTest, UninstallingAppClosesDialog) {
177 ShowAppInfo(kTestExtensionId);
178 ASSERT_TRUE(widget_);
151 EXPECT_FALSE(widget_->IsClosed()); 179 EXPECT_FALSE(widget_->IsClosed());
152 EXPECT_FALSE(widget_destroyed_);
153 UninstallApp(kTestExtensionId); 180 UninstallApp(kTestExtensionId);
154 base::RunLoop().RunUntilIdle(); 181 base::RunLoop().RunUntilIdle();
155 EXPECT_TRUE(widget_destroyed_); 182 EXPECT_FALSE(widget_);
156 } 183 }
157 184
158 // Tests that the dialog does not close when a different app is uninstalled. 185 // Tests that the dialog does not close when a different app is uninstalled.
159 TEST_F(AppInfoDialogViewsTest, UninstallingOtherAppDoesNotCloseDialog) { 186 TEST_F(AppInfoDialogViewsTest, UninstallingOtherAppDoesNotCloseDialog) {
187 ShowAppInfo(kTestExtensionId);
160 extension_environment_.MakePackagedApp(kTestOtherExtensionId, true); 188 extension_environment_.MakePackagedApp(kTestOtherExtensionId, true);
161 189 ASSERT_TRUE(widget_);
162 EXPECT_FALSE(widget_->IsClosed()); 190 EXPECT_FALSE(widget_->IsClosed());
163 EXPECT_FALSE(widget_destroyed_);
164 UninstallApp(kTestOtherExtensionId); 191 UninstallApp(kTestOtherExtensionId);
165 base::RunLoop().RunUntilIdle(); 192 base::RunLoop().RunUntilIdle();
166 EXPECT_FALSE(widget_destroyed_); 193 EXPECT_TRUE(widget_);
167 } 194 }
168 195
169 // Tests that the dialog closes when the current profile is destroyed. 196 // Tests that the dialog closes when the current profile is destroyed.
170 TEST_F(AppInfoDialogViewsTest, DestroyedProfileClosesDialog) { 197 TEST_F(AppInfoDialogViewsTest, DestroyedProfileClosesDialog) {
198 ShowAppInfo(kTestExtensionId);
171 // First delete the test browser window. This ensures the test harness isn't 199 // First delete the test browser window. This ensures the test harness isn't
172 // surprised by it being closed in response to the profile deletion below. 200 // surprised by it being closed in response to the profile deletion below.
173 // Note the base class doesn't own the profile, so that part is skipped. 201 // Note the base class doesn't own the profile, so that part is skipped.
174 DestroyBrowserAndProfile(); 202 DestroyBrowserAndProfile();
175 203
176 // The following does nothing: it just ensures the Widget close is being 204 // The following does nothing: it just ensures the Widget close is being
177 // triggered by the DeleteProfile() call rather than the line above. 205 // triggered by the DeleteProfile() call rather than the line above.
178 base::RunLoop().RunUntilIdle(); 206 base::RunLoop().RunUntilIdle();
179 207
208 ASSERT_TRUE(widget_);
180 EXPECT_FALSE(widget_->IsClosed()); 209 EXPECT_FALSE(widget_->IsClosed());
181 EXPECT_FALSE(widget_destroyed_);
182 extension_environment_.DeleteProfile(); 210 extension_environment_.DeleteProfile();
183 211
184 base::RunLoop().RunUntilIdle(); 212 base::RunLoop().RunUntilIdle();
185 EXPECT_TRUE(widget_destroyed_); 213 EXPECT_FALSE(widget_);
186 } 214 }
187 215
188 // Tests that the dialog does not close when a different profile is destroyed. 216 // Tests that the dialog does not close when a different profile is destroyed.
189 TEST_F(AppInfoDialogViewsTest, DestroyedOtherProfileDoesNotCloseDialog) { 217 TEST_F(AppInfoDialogViewsTest, DestroyedOtherProfileDoesNotCloseDialog) {
218 ShowAppInfo(kTestExtensionId);
190 std::unique_ptr<TestingProfile> other_profile(new TestingProfile); 219 std::unique_ptr<TestingProfile> other_profile(new TestingProfile);
191 extension_environment_.CreateExtensionServiceForProfile(other_profile.get()); 220 extension_environment_.CreateExtensionServiceForProfile(other_profile.get());
192 221
193 scoped_refptr<const extensions::Extension> other_app = 222 scoped_refptr<const extensions::Extension> other_app =
194 extension_environment_.MakePackagedApp(kTestOtherExtensionId, false); 223 extension_environment_.MakePackagedApp(kTestOtherExtensionId, false);
195 extensions::ExtensionSystem::Get(other_profile.get()) 224 extensions::ExtensionSystem::Get(other_profile.get())
196 ->extension_service() 225 ->extension_service()
197 ->AddExtension(other_app.get()); 226 ->AddExtension(other_app.get());
198 227
228 ASSERT_TRUE(widget_);
199 EXPECT_FALSE(widget_->IsClosed()); 229 EXPECT_FALSE(widget_->IsClosed());
200 EXPECT_FALSE(widget_destroyed_);
201 other_profile.reset(); 230 other_profile.reset();
202 base::RunLoop().RunUntilIdle(); 231 base::RunLoop().RunUntilIdle();
203 EXPECT_FALSE(widget_destroyed_); 232 EXPECT_TRUE(widget_);
204 } 233 }
205 234
206 // Tests that clicking the View in Store link opens a browser tab and closes the 235 // Tests that clicking the View in Store link opens a browser tab and closes the
207 // dialog cleanly. 236 // dialog cleanly.
208 TEST_F(AppInfoDialogViewsTest, ViewInStore) { 237 TEST_F(AppInfoDialogViewsTest, ViewInStore) {
238 ShowAppInfo(kTestExtensionId);
209 EXPECT_TRUE(extension_->from_webstore()); // Otherwise there is no link. 239 EXPECT_TRUE(extension_->from_webstore()); // Otherwise there is no link.
210 views::Link* link = test::AppInfoDialogTestApi(dialog_).view_in_store_link(); 240 views::Link* link = test::AppInfoDialogTestApi(dialog_).view_in_store_link();
211 EXPECT_TRUE(link); 241 EXPECT_TRUE(link);
212 242
213 TabStripModel* tabs = browser()->tab_strip_model(); 243 TabStripModel* tabs = browser()->tab_strip_model();
214 EXPECT_EQ(0, tabs->count()); 244 EXPECT_EQ(0, tabs->count());
215 245
246 ASSERT_TRUE(widget_);
216 EXPECT_FALSE(widget_->IsClosed()); 247 EXPECT_FALSE(widget_->IsClosed());
217 EXPECT_FALSE(widget_destroyed_);
218 link->OnKeyPressed(ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, 0)); 248 link->OnKeyPressed(ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, 0));
219 249
250 ASSERT_TRUE(widget_);
220 EXPECT_TRUE(widget_->IsClosed()); 251 EXPECT_TRUE(widget_->IsClosed());
221 EXPECT_FALSE(widget_destroyed_);
222 252
223 EXPECT_EQ(1, tabs->count()); 253 EXPECT_EQ(1, tabs->count());
224 content::WebContents* web_contents = tabs->GetWebContentsAt(0); 254 content::WebContents* web_contents = tabs->GetWebContentsAt(0);
225 255
226 std::string url = "https://chrome.google.com/webstore/detail/"; 256 std::string url = "https://chrome.google.com/webstore/detail/";
227 url += kTestExtensionId; 257 url += kTestExtensionId;
228 url += "?utm_source=chrome-app-launcher-info-dialog"; 258 url += "?utm_source=chrome-app-launcher-info-dialog";
229 EXPECT_EQ(GURL(url), web_contents->GetURL()); 259 EXPECT_EQ(GURL(url), web_contents->GetURL());
230 260
231 base::RunLoop().RunUntilIdle(); 261 base::RunLoop().RunUntilIdle();
232 EXPECT_TRUE(widget_destroyed_); 262 EXPECT_FALSE(widget_);
233 } 263 }
264
265 #if defined(OS_CHROMEOS)
266 TEST_F(AppInfoDialogViewsTest, ArcAppInfoLinks) {
267 ShowAppInfo(extension_misc::kChromeAppId);
268 EXPECT_FALSE(widget_->IsClosed());
269 // App Info should not have ARC App info links section because ARC Settings
270 // app is not available yet.
271 EXPECT_FALSE(dialog_->arc_app_info_links_for_test());
272
273 // Re-show App Info but with ARC Settings app enabled.
274 CloseAppInfo();
275 ArcAppListPrefs* arc_prefs =
276 ArcAppListPrefs::Get(extension_environment_.profile());
277 ASSERT_TRUE(arc_prefs);
278 arc::mojom::AppHost* app_host = arc_prefs;
279 app_host->OnAppListRefreshed(GetArcSettingsAppInfo());
280 EXPECT_TRUE(arc_prefs->IsRegistered(arc::kSettingsAppId));
281 ShowAppInfo(extension_misc::kChromeAppId);
282 EXPECT_FALSE(widget_->IsClosed());
283 EXPECT_TRUE(dialog_->arc_app_info_links_for_test());
284
285 // Re-show App Info but for non-primary profile.
286 CloseAppInfo();
287 std::unique_ptr<TestingProfile> other_profile =
288 base::MakeUnique<TestingProfile>();
289 extension_environment_.CreateExtensionServiceForProfile(other_profile.get());
290 scoped_refptr<const extensions::Extension> other_app =
291 extension_environment_.MakePackagedApp(extension_misc::kChromeAppId,
292 true);
293 extensions::ExtensionSystem::Get(other_profile.get())
294 ->extension_service()
295 ->AddExtension(other_app.get());
296 ShowAppInfoForProfile(extension_misc::kChromeAppId, other_profile.get());
297 EXPECT_FALSE(widget_->IsClosed());
298 // The ARC App info links are not available if ARC is not allowed for
299 // secondary profile.
300 EXPECT_FALSE(dialog_->arc_app_info_links_for_test());
301 }
302 #endif
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698