Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / extensions / crx_installer_browsertest.cc
blobe32bc1bd0028f20325f8e4901da4ec14f3163cee
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/memory/ref_counted.h"
6 #include "chrome/browser/download/download_crx_util.h"
7 #include "chrome/browser/extensions/browser_action_test_util.h"
8 #include "chrome/browser/extensions/crx_installer.h"
9 #include "chrome/browser/extensions/extension_browsertest.h"
10 #include "chrome/browser/extensions/extension_install_prompt.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/browser_window.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/test/base/ui_test_utils.h"
18 #include "content/public/browser/download_manager.h"
19 #include "content/public/browser/render_view_host.h"
20 #include "content/public/test/browser_test_utils.h"
21 #include "content/public/test/download_test_observer.h"
22 #include "extensions/browser/extension_system.h"
23 #include "extensions/common/extension.h"
24 #include "extensions/common/feature_switch.h"
25 #include "extensions/common/file_util.h"
26 #include "extensions/common/permissions/permission_set.h"
27 #include "extensions/common/switches.h"
28 #include "grit/generated_resources.h"
29 #include "ui/base/l10n/l10n_util.h"
31 #if defined(OS_CHROMEOS)
32 #include "chrome/browser/chromeos/login/fake_user_manager.h"
33 #include "chrome/browser/chromeos/login/user_manager.h"
34 #endif
36 class SkBitmap;
38 namespace extensions {
40 namespace {
42 class MockInstallPrompt;
44 // This class holds information about things that happen with a
45 // MockInstallPrompt. We create the MockInstallPrompt but need to pass
46 // ownership of it to CrxInstaller, so it isn't safe to hang this data on
47 // MockInstallPrompt itself becuase we can't guarantee it's lifetime.
48 class MockPromptProxy :
49 public base::RefCountedThreadSafe<MockPromptProxy> {
50 public:
51 explicit MockPromptProxy(content::WebContents* web_contents);
53 bool did_succeed() const { return !extension_id_.empty(); }
54 const std::string& extension_id() { return extension_id_; }
55 bool confirmation_requested() const { return confirmation_requested_; }
56 const base::string16& error() const { return error_; }
58 // To have any effect, this should be called before CreatePrompt.
59 void set_record_oauth2_grant(bool record_oauth2_grant) {
60 record_oauth2_grant_.reset(new bool(record_oauth2_grant));
63 void set_extension_id(const std::string& id) { extension_id_ = id; }
64 void set_confirmation_requested() { confirmation_requested_ = true; }
65 void set_error(const base::string16& error) { error_ = error; }
67 scoped_ptr<ExtensionInstallPrompt> CreatePrompt();
69 private:
70 friend class base::RefCountedThreadSafe<MockPromptProxy>;
71 virtual ~MockPromptProxy();
73 // Data used to create a prompt.
74 content::WebContents* web_contents_;
75 scoped_ptr<bool> record_oauth2_grant_;
77 // Data reported back to us by the prompt we created.
78 bool confirmation_requested_;
79 std::string extension_id_;
80 base::string16 error_;
83 class MockInstallPrompt : public ExtensionInstallPrompt {
84 public:
85 MockInstallPrompt(content::WebContents* web_contents,
86 MockPromptProxy* proxy) :
87 ExtensionInstallPrompt(web_contents),
88 proxy_(proxy) {}
90 void set_record_oauth2_grant(bool record) { record_oauth2_grant_ = record; }
92 // Overriding some of the ExtensionInstallUI API.
93 virtual void ConfirmInstall(
94 Delegate* delegate,
95 const Extension* extension,
96 const ShowDialogCallback& show_dialog_callback) OVERRIDE {
97 proxy_->set_confirmation_requested();
98 delegate->InstallUIProceed();
100 virtual void OnInstallSuccess(const Extension* extension,
101 SkBitmap* icon) OVERRIDE {
102 proxy_->set_extension_id(extension->id());
103 base::MessageLoopForUI::current()->Quit();
105 virtual void OnInstallFailure(const CrxInstallerError& error) OVERRIDE {
106 proxy_->set_error(error.message());
107 base::MessageLoopForUI::current()->Quit();
110 private:
111 scoped_refptr<MockPromptProxy> proxy_;
115 MockPromptProxy::MockPromptProxy(content::WebContents* web_contents) :
116 web_contents_(web_contents),
117 confirmation_requested_(false) {
120 MockPromptProxy::~MockPromptProxy() {}
122 scoped_ptr<ExtensionInstallPrompt> MockPromptProxy::CreatePrompt() {
123 scoped_ptr<MockInstallPrompt> prompt(
124 new MockInstallPrompt(web_contents_, this));
125 if (record_oauth2_grant_.get())
126 prompt->set_record_oauth2_grant(*record_oauth2_grant_.get());
127 return prompt.PassAs<ExtensionInstallPrompt>();
131 scoped_refptr<MockPromptProxy> CreateMockPromptProxyForBrowser(
132 Browser* browser) {
133 return new MockPromptProxy(
134 browser->tab_strip_model()->GetActiveWebContents());
137 } // namespace
139 class ExtensionCrxInstallerTest : public ExtensionBrowserTest {
140 public:
141 scoped_ptr<WebstoreInstaller::Approval> GetApproval(
142 const char* manifest_dir,
143 const std::string& id,
144 bool strict_manifest_checks) {
145 scoped_ptr<WebstoreInstaller::Approval> result;
147 base::FilePath ext_path = test_data_dir_.AppendASCII(manifest_dir);
148 std::string error;
149 scoped_ptr<base::DictionaryValue> parsed_manifest(
150 file_util::LoadManifest(ext_path, &error));
151 if (!parsed_manifest.get() || !error.empty())
152 return result.Pass();
154 return WebstoreInstaller::Approval::CreateWithNoInstallPrompt(
155 browser()->profile(),
157 parsed_manifest.Pass(),
158 strict_manifest_checks);
161 void RunCrxInstaller(const WebstoreInstaller::Approval* approval,
162 scoped_ptr<ExtensionInstallPrompt> prompt,
163 const base::FilePath& crx_path) {
164 ExtensionService* service = extensions::ExtensionSystem::Get(
165 browser()->profile())->extension_service();
166 scoped_refptr<CrxInstaller> installer(
167 CrxInstaller::Create(service, prompt.Pass(), approval));
168 installer->set_allow_silent_install(true);
169 installer->set_is_gallery_install(true);
170 installer->InstallCrx(crx_path);
171 content::RunMessageLoop();
174 // Installs a crx from |crx_relpath| (a path relative to the extension test
175 // data dir) with expected id |id|.
176 void InstallWithPrompt(const char* ext_relpath,
177 const std::string& id,
178 scoped_refptr<MockPromptProxy> mock_install_prompt) {
179 base::FilePath ext_path = test_data_dir_.AppendASCII(ext_relpath);
181 scoped_ptr<WebstoreInstaller::Approval> approval;
182 if (!id.empty())
183 approval = GetApproval(ext_relpath, id, true);
185 base::FilePath crx_path = PackExtension(ext_path);
186 EXPECT_FALSE(crx_path.empty());
187 RunCrxInstaller(approval.get(), mock_install_prompt->CreatePrompt(),
188 crx_path);
190 EXPECT_TRUE(mock_install_prompt->did_succeed());
193 // Installs an extension and checks that it has scopes granted IFF
194 // |record_oauth2_grant| is true.
195 void CheckHasEmptyScopesAfterInstall(const std::string& ext_relpath,
196 bool record_oauth2_grant) {
197 CommandLine::ForCurrentProcess()->AppendSwitch(
198 switches::kEnableExperimentalExtensionApis);
200 scoped_refptr<MockPromptProxy> mock_prompt =
201 CreateMockPromptProxyForBrowser(browser());
203 mock_prompt->set_record_oauth2_grant(record_oauth2_grant);
204 InstallWithPrompt("browsertest/scopes", std::string(), mock_prompt);
206 scoped_refptr<PermissionSet> permissions =
207 ExtensionPrefs::Get(browser()->profile())
208 ->GetGrantedPermissions(mock_prompt->extension_id());
209 ASSERT_TRUE(permissions.get());
213 #if defined(OS_CHROMEOS)
214 #define MAYBE_Whitelisting DISABLED_Whitelisting
215 #else
216 #define MAYBE_Whitelisting Whitelisting
217 #endif
218 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, MAYBE_Whitelisting) {
219 std::string id = "hdgllgikmikobbofgnabhfimcfoopgnd";
220 ExtensionService* service = extensions::ExtensionSystem::Get(
221 browser()->profile())->extension_service();
223 // Even whitelisted extensions with NPAPI should not prompt.
224 scoped_refptr<MockPromptProxy> mock_prompt =
225 CreateMockPromptProxyForBrowser(browser());
226 InstallWithPrompt("uitest/plugins", id, mock_prompt);
227 EXPECT_FALSE(mock_prompt->confirmation_requested());
228 EXPECT_TRUE(service->GetExtensionById(id, false));
231 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
232 GalleryInstallGetsExperimental) {
233 // We must modify the command line temporarily in order to pack an extension
234 // that requests the experimental permission.
235 CommandLine* command_line = CommandLine::ForCurrentProcess();
236 CommandLine old_command_line = *command_line;
237 command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
238 base::FilePath crx_path = PackExtension(
239 test_data_dir_.AppendASCII("experimental"));
240 ASSERT_FALSE(crx_path.empty());
242 // Now reset the command line so that we are testing specifically whether
243 // installing from webstore enables experimental permissions.
244 *(CommandLine::ForCurrentProcess()) = old_command_line;
246 EXPECT_FALSE(InstallExtension(crx_path, 0));
247 EXPECT_TRUE(InstallExtensionFromWebstore(crx_path, 1));
250 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, PlatformAppCrx) {
251 CommandLine::ForCurrentProcess()->AppendSwitch(
252 switches::kEnableExperimentalExtensionApis);
253 EXPECT_TRUE(InstallExtension(
254 test_data_dir_.AppendASCII("minimal_platform_app.crx"), 1));
257 // http://crbug.com/136397
258 #if defined(OS_CHROMEOS)
259 #define MAYBE_PackAndInstallExtension DISABLED_PackAndInstallExtension
260 #else
261 #define MAYBE_PackAndInstallExtension PackAndInstallExtension
262 #endif
263 IN_PROC_BROWSER_TEST_F(
264 ExtensionCrxInstallerTest, MAYBE_PackAndInstallExtension) {
265 if (!FeatureSwitch::easy_off_store_install()->IsEnabled())
266 return;
268 const int kNumDownloadsExpected = 1;
270 LOG(ERROR) << "PackAndInstallExtension: Packing extension";
271 base::FilePath crx_path = PackExtension(
272 test_data_dir_.AppendASCII("common/background_page"));
273 ASSERT_FALSE(crx_path.empty());
274 std::string crx_path_string(crx_path.value().begin(), crx_path.value().end());
275 GURL url = GURL(std::string("file:///").append(crx_path_string));
277 scoped_refptr<MockPromptProxy> mock_prompt =
278 CreateMockPromptProxyForBrowser(browser());
279 download_crx_util::SetMockInstallPromptForTesting(
280 mock_prompt->CreatePrompt());
282 LOG(ERROR) << "PackAndInstallExtension: Getting download manager";
283 content::DownloadManager* download_manager =
284 content::BrowserContext::GetDownloadManager(browser()->profile());
286 LOG(ERROR) << "PackAndInstallExtension: Setting observer";
287 scoped_ptr<content::DownloadTestObserver> observer(
288 new content::DownloadTestObserverTerminal(
289 download_manager, kNumDownloadsExpected,
290 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT));
291 LOG(ERROR) << "PackAndInstallExtension: Navigating to URL";
292 ui_test_utils::NavigateToURLWithDisposition(browser(), url, CURRENT_TAB,
293 ui_test_utils::BROWSER_TEST_NONE);
295 EXPECT_TRUE(WaitForCrxInstallerDone());
296 LOG(ERROR) << "PackAndInstallExtension: Extension install";
297 EXPECT_TRUE(mock_prompt->confirmation_requested());
298 LOG(ERROR) << "PackAndInstallExtension: Extension install confirmed";
301 // Tests that scopes are only granted if |record_oauth2_grant_| on the prompt is
302 // true.
303 #if defined(OS_WIN)
304 #define MAYBE_GrantScopes DISABLED_GrantScopes
305 #else
306 #define MAYBE_GrantScopes GrantScopes
307 #endif
308 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, MAYBE_GrantScopes) {
309 EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall("browsertest/scopes",
310 true));
313 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, DoNotGrantScopes) {
314 EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall("browsertest/scopes",
315 false));
318 // Off-store install cannot yet be disabled on Aura.
319 #if defined(USE_AURA)
320 #define MAYBE_AllowOffStore DISABLED_AllowOffStore
321 #else
322 #define MAYBE_AllowOffStore AllowOffStore
323 #endif
324 // Crashy: http://crbug.com/140893
325 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, DISABLED_AllowOffStore) {
326 ExtensionService* service = extensions::ExtensionSystem::Get(
327 browser()->profile())->extension_service();
328 const bool kTestData[] = {false, true};
330 for (size_t i = 0; i < arraysize(kTestData); ++i) {
331 scoped_refptr<MockPromptProxy> mock_prompt =
332 CreateMockPromptProxyForBrowser(browser());
334 scoped_refptr<CrxInstaller> crx_installer(
335 CrxInstaller::Create(service, mock_prompt->CreatePrompt()));
336 crx_installer->set_install_cause(
337 extension_misc::INSTALL_CAUSE_USER_DOWNLOAD);
339 if (kTestData[i]) {
340 crx_installer->set_off_store_install_allow_reason(
341 CrxInstaller::OffStoreInstallAllowedInTest);
344 crx_installer->InstallCrx(test_data_dir_.AppendASCII("good.crx"));
345 EXPECT_EQ(kTestData[i],
346 WaitForExtensionInstall()) << kTestData[i];
347 EXPECT_EQ(kTestData[i], mock_prompt->did_succeed());
348 EXPECT_EQ(kTestData[i], mock_prompt->confirmation_requested()) <<
349 kTestData[i];
350 if (kTestData[i]) {
351 EXPECT_EQ(base::string16(), mock_prompt->error()) << kTestData[i];
352 } else {
353 EXPECT_EQ(l10n_util::GetStringUTF16(
354 IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE),
355 mock_prompt->error()) << kTestData[i];
360 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, HiDpiThemeTest) {
361 base::FilePath crx_path = test_data_dir_.AppendASCII("theme_hidpi_crx");
362 crx_path = crx_path.AppendASCII("theme_hidpi.crx");
364 ASSERT_TRUE(InstallExtension(crx_path,1));
366 const std::string extension_id("gllekhaobjnhgeagipipnkpmmmpchacm");
367 ExtensionService* service = extensions::ExtensionSystem::Get(
368 browser()->profile())->extension_service();
369 ASSERT_TRUE(service);
370 const extensions::Extension* extension =
371 service->GetExtensionById(extension_id, false);
372 ASSERT_TRUE(extension);
373 EXPECT_EQ(extension_id, extension->id());
375 UninstallExtension(extension_id);
376 EXPECT_FALSE(service->GetExtensionById(extension_id, false));
379 // See http://crbug.com/315299.
380 #if defined(OS_WIN)
381 #define MAYBE_InstallDelayedUntilNextUpdate \
382 DISABLED_InstallDelayedUntilNextUpdate
383 #else
384 #define MAYBE_InstallDelayedUntilNextUpdate InstallDelayedUntilNextUpdate
385 #endif // defined(OS_WIN)
386 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
387 MAYBE_InstallDelayedUntilNextUpdate) {
388 const std::string extension_id("ldnnhddmnhbkjipkidpdiheffobcpfmf");
389 base::FilePath crx_path = test_data_dir_.AppendASCII("delayed_install");
390 ExtensionSystem* extension_system = extensions::ExtensionSystem::Get(
391 browser()->profile());
392 ExtensionService* service = extension_system->extension_service();
393 ASSERT_TRUE(service);
395 // Install version 1 of the test extension. This extension does not have
396 // a background page but does have a browser action.
397 ASSERT_TRUE(InstallExtension(crx_path.AppendASCII("v1.crx"), 1));
398 const extensions::Extension* extension =
399 service->GetExtensionById(extension_id, false);
400 ASSERT_TRUE(extension);
401 ASSERT_EQ(extension_id, extension->id());
402 ASSERT_EQ("1.0", extension->version()->GetString());
404 // Make test extension non-idle by opening the extension's browser action
405 // popup. This should cause the installation to be delayed.
406 content::WindowedNotificationObserver loading_observer(
407 chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
408 content::Source<Profile>(profile()));
409 BrowserActionTestUtil util(browser());
410 // There is only one extension, so just click the first browser action.
411 ASSERT_EQ(1, util.NumberOfBrowserActions());
412 util.Press(0);
413 loading_observer.Wait();
414 ExtensionHost* extension_host =
415 content::Details<ExtensionHost>(loading_observer.details()).ptr();
417 // Install version 2 of the extension and check that it is indeed delayed.
418 ASSERT_TRUE(UpdateExtensionWaitForIdle(
419 extension_id, crx_path.AppendASCII("v2.crx"), 0));
421 ASSERT_EQ(1u, service->delayed_installs()->size());
422 extension = service->GetExtensionById(extension_id, false);
423 ASSERT_EQ("1.0", extension->version()->GetString());
425 // Make the extension idle again by closing the popup. This should not trigger
426 //the delayed install.
427 content::RenderProcessHostWatcher terminated_observer(
428 extension_host->render_process_host(),
429 content::RenderProcessHostWatcher::WATCH_FOR_HOST_DESTRUCTION);
430 extension_host->render_view_host()->ClosePage();
431 terminated_observer.Wait();
432 ASSERT_EQ(1u, service->delayed_installs()->size());
434 // Install version 3 of the extension. Because the extension is idle,
435 // this install should succeed.
436 ASSERT_TRUE(UpdateExtensionWaitForIdle(
437 extension_id, crx_path.AppendASCII("v3.crx"), 0));
438 extension = service->GetExtensionById(extension_id, false);
439 ASSERT_EQ("3.0", extension->version()->GetString());
441 // The version 2 delayed install should be cleaned up, and finishing
442 // delayed extension installation shouldn't break anything.
443 ASSERT_EQ(0u, service->delayed_installs()->size());
444 service->MaybeFinishDelayedInstallations();
445 extension = service->GetExtensionById(extension_id, false);
446 ASSERT_EQ("3.0", extension->version()->GetString());
449 #if defined(FULL_SAFE_BROWSING)
450 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, Blacklist) {
451 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
452 new FakeSafeBrowsingDatabaseManager(true));
453 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
455 blacklist_db->SetUnsafe("gllekhaobjnhgeagipipnkpmmmpchacm");
457 base::FilePath crx_path = test_data_dir_.AppendASCII("theme_hidpi_crx")
458 .AppendASCII("theme_hidpi.crx");
459 EXPECT_FALSE(InstallExtension(crx_path, 0));
461 #endif
463 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, NonStrictManifestCheck) {
464 scoped_refptr<MockPromptProxy> mock_prompt =
465 CreateMockPromptProxyForBrowser(browser());
467 // We want to simulate the case where the webstore sends a more recent
468 // version of the manifest, but the downloaded .crx file is old since
469 // the newly published version hasn't fully propagated to all the download
470 // servers yet. So load the v2 manifest, but then install the v1 crx file.
471 std::string id = "lhnaeclnpobnlbjbgogdanmhadigfnjp";
472 scoped_ptr<WebstoreInstaller::Approval> approval =
473 GetApproval("crx_installer/v2_no_permission_change/", id, false);
475 RunCrxInstaller(approval.get(), mock_prompt->CreatePrompt(),
476 test_data_dir_.AppendASCII("crx_installer/v1.crx"));
478 EXPECT_TRUE(mock_prompt->did_succeed());
481 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, KioskOnlyTest) {
482 base::FilePath crx_path =
483 test_data_dir_.AppendASCII("kiosk/kiosk_only.crx");
484 EXPECT_FALSE(InstallExtension(crx_path, 0));
485 #if defined(OS_CHROMEOS)
486 // Simulate ChromeOS kiosk mode. |scoped_user_manager| will take over
487 // lifetime of |user_manager|.
488 chromeos::FakeUserManager* fake_user_manager =
489 new chromeos::FakeUserManager();
490 fake_user_manager->AddKioskAppUser("example@example.com");
491 fake_user_manager->LoginUser("example@example.com");
492 chromeos::ScopedUserManagerEnabler scoped_user_manager(fake_user_manager);
493 EXPECT_TRUE(InstallExtension(crx_path, 1));
494 #endif
497 } // namespace extensions