| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/extensions/crx_installer.h" | 5 #include "chrome/browser/extensions/crx_installer.h" |
| 6 | 6 |
| 7 #include "base/at_exit.h" | 7 #include "base/at_exit.h" |
| 8 #include "base/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
| 9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "chrome/browser/download/download_crx_util.h" | 10 #include "chrome/browser/download/download_crx_util.h" |
| 11 #include "chrome/browser/extensions/browser_action_test_util.h" | 11 #include "chrome/browser/extensions/browser_action_test_util.h" |
| 12 #include "chrome/browser/extensions/extension_browsertest.h" | 12 #include "chrome/browser/extensions/extension_browsertest.h" |
| 13 #include "chrome/browser/extensions/extension_install_prompt.h" | 13 #include "chrome/browser/extensions/extension_install_prompt.h" |
| 14 #include "chrome/browser/extensions/extension_service.h" | 14 #include "chrome/browser/extensions/extension_service.h" |
| 15 #include "chrome/browser/extensions/extension_util.h" | 15 #include "chrome/browser/extensions/extension_util.h" |
| 16 #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h" | 16 #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h" |
| 17 #include "chrome/browser/extensions/test_extension_dir.h" |
| 17 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
| 18 #include "chrome/browser/ui/browser.h" | 19 #include "chrome/browser/ui/browser.h" |
| 19 #include "chrome/browser/ui/browser_window.h" | 20 #include "chrome/browser/ui/browser_window.h" |
| 20 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 21 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 21 #include "chrome/grit/generated_resources.h" | 22 #include "chrome/grit/generated_resources.h" |
| 22 #include "chrome/test/base/ui_test_utils.h" | 23 #include "chrome/test/base/ui_test_utils.h" |
| 23 #include "content/public/browser/browser_thread.h" | 24 #include "content/public/browser/browser_thread.h" |
| 24 #include "content/public/browser/download_manager.h" | 25 #include "content/public/browser/download_manager.h" |
| 25 #include "content/public/browser/render_view_host.h" | 26 #include "content/public/browser/render_view_host.h" |
| 26 #include "content/public/test/browser_test_utils.h" | 27 #include "content/public/test/browser_test_utils.h" |
| 27 #include "content/public/test/download_test_observer.h" | 28 #include "content/public/test/download_test_observer.h" |
| 28 #include "content/public/test/test_utils.h" | 29 #include "content/public/test/test_utils.h" |
| 29 #include "extensions/browser/extension_prefs.h" | 30 #include "extensions/browser/extension_prefs.h" |
| 31 #include "extensions/browser/extension_registry.h" |
| 30 #include "extensions/browser/extension_system.h" | 32 #include "extensions/browser/extension_system.h" |
| 31 #include "extensions/browser/management_policy.h" | 33 #include "extensions/browser/management_policy.h" |
| 32 #include "extensions/browser/notification_types.h" | 34 #include "extensions/browser/notification_types.h" |
| 33 #include "extensions/common/extension.h" | 35 #include "extensions/common/extension.h" |
| 34 #include "extensions/common/feature_switch.h" | 36 #include "extensions/common/feature_switch.h" |
| 35 #include "extensions/common/file_util.h" | 37 #include "extensions/common/file_util.h" |
| 36 #include "extensions/common/permissions/permission_set.h" | 38 #include "extensions/common/permissions/permission_set.h" |
| 37 #include "extensions/common/switches.h" | 39 #include "extensions/common/switches.h" |
| 38 #include "ui/base/l10n/l10n_util.h" | 40 #include "ui/base/l10n/l10n_util.h" |
| 39 | 41 |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 ->GetGrantedPermissions(mock_prompt->extension_id()); | 233 ->GetGrantedPermissions(mock_prompt->extension_id()); |
| 232 ASSERT_TRUE(permissions.get()); | 234 ASSERT_TRUE(permissions.get()); |
| 233 } | 235 } |
| 234 }; | 236 }; |
| 235 | 237 |
| 236 // This test is skipped on ChromeOS because it requires the NPAPI, | 238 // This test is skipped on ChromeOS because it requires the NPAPI, |
| 237 // which is not available on that platform. | 239 // which is not available on that platform. |
| 238 #if !defined(OS_CHROMEOS) | 240 #if !defined(OS_CHROMEOS) |
| 239 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, Whitelisting) { | 241 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, Whitelisting) { |
| 240 std::string id = "hdgllgikmikobbofgnabhfimcfoopgnd"; | 242 std::string id = "hdgllgikmikobbofgnabhfimcfoopgnd"; |
| 241 ExtensionService* service = extensions::ExtensionSystem::Get( | 243 ExtensionRegistry* registry = ExtensionRegistry::Get( |
| 242 browser()->profile())->extension_service(); | 244 browser()->profile()); |
| 243 | 245 |
| 244 // Even whitelisted extensions with NPAPI should not prompt. | 246 // Even whitelisted extensions with NPAPI should not prompt. |
| 245 scoped_refptr<MockPromptProxy> mock_prompt = | 247 scoped_refptr<MockPromptProxy> mock_prompt = |
| 246 CreateMockPromptProxyForBrowser(browser()); | 248 CreateMockPromptProxyForBrowser(browser()); |
| 247 InstallWithPrompt("uitest/plugins", id, mock_prompt); | 249 InstallWithPrompt("uitest/plugins", id, mock_prompt); |
| 248 EXPECT_FALSE(mock_prompt->confirmation_requested()); | 250 EXPECT_FALSE(mock_prompt->confirmation_requested()); |
| 249 EXPECT_TRUE(service->GetExtensionById(id, false)); | 251 EXPECT_TRUE(registry->enabled_extensions().GetByID(id)); |
| 250 } | 252 } |
| 251 #endif | 253 #endif |
| 252 | 254 |
| 253 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, | 255 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, |
| 254 GalleryInstallGetsExperimental) { | 256 GalleryInstallGetsExperimental) { |
| 255 // We must modify the command line temporarily in order to pack an extension | 257 // We must modify the command line temporarily in order to pack an extension |
| 256 // that requests the experimental permission. | 258 // that requests the experimental permission. |
| 257 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 259 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 258 CommandLine old_command_line = *command_line; | 260 CommandLine old_command_line = *command_line; |
| 259 command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis); | 261 command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 } | 368 } |
| 367 } | 369 } |
| 368 | 370 |
| 369 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, HiDpiThemeTest) { | 371 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, HiDpiThemeTest) { |
| 370 base::FilePath crx_path = test_data_dir_.AppendASCII("theme_hidpi_crx"); | 372 base::FilePath crx_path = test_data_dir_.AppendASCII("theme_hidpi_crx"); |
| 371 crx_path = crx_path.AppendASCII("theme_hidpi.crx"); | 373 crx_path = crx_path.AppendASCII("theme_hidpi.crx"); |
| 372 | 374 |
| 373 ASSERT_TRUE(InstallExtension(crx_path, 1)); | 375 ASSERT_TRUE(InstallExtension(crx_path, 1)); |
| 374 | 376 |
| 375 const std::string extension_id("gllekhaobjnhgeagipipnkpmmmpchacm"); | 377 const std::string extension_id("gllekhaobjnhgeagipipnkpmmmpchacm"); |
| 376 ExtensionService* service = extensions::ExtensionSystem::Get( | 378 ExtensionRegistry* registry = ExtensionRegistry::Get( |
| 377 browser()->profile())->extension_service(); | 379 browser()->profile()); |
| 378 ASSERT_TRUE(service); | |
| 379 const extensions::Extension* extension = | 380 const extensions::Extension* extension = |
| 380 service->GetExtensionById(extension_id, false); | 381 registry->enabled_extensions().GetByID(extension_id); |
| 381 ASSERT_TRUE(extension); | 382 ASSERT_TRUE(extension); |
| 382 EXPECT_EQ(extension_id, extension->id()); | 383 EXPECT_EQ(extension_id, extension->id()); |
| 383 | 384 |
| 384 UninstallExtension(extension_id); | 385 UninstallExtension(extension_id); |
| 385 EXPECT_FALSE(service->GetExtensionById(extension_id, false)); | 386 EXPECT_FALSE(registry->enabled_extensions().GetByID(extension_id)); |
| 386 } | 387 } |
| 387 | 388 |
| 388 // See http://crbug.com/315299. | 389 // See http://crbug.com/315299. |
| 389 #if defined(OS_WIN) || defined(OS_LINUX) | 390 #if defined(OS_WIN) || defined(OS_LINUX) |
| 390 #define MAYBE_InstallDelayedUntilNextUpdate \ | 391 #define MAYBE_InstallDelayedUntilNextUpdate \ |
| 391 DISABLED_InstallDelayedUntilNextUpdate | 392 DISABLED_InstallDelayedUntilNextUpdate |
| 392 #else | 393 #else |
| 393 #define MAYBE_InstallDelayedUntilNextUpdate InstallDelayedUntilNextUpdate | 394 #define MAYBE_InstallDelayedUntilNextUpdate InstallDelayedUntilNextUpdate |
| 394 #endif | 395 #endif |
| 395 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, | 396 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, |
| 396 MAYBE_InstallDelayedUntilNextUpdate) { | 397 MAYBE_InstallDelayedUntilNextUpdate) { |
| 397 const std::string extension_id("ldnnhddmnhbkjipkidpdiheffobcpfmf"); | 398 const std::string extension_id("ldnnhddmnhbkjipkidpdiheffobcpfmf"); |
| 398 base::FilePath crx_path = test_data_dir_.AppendASCII("delayed_install"); | 399 base::FilePath crx_path = test_data_dir_.AppendASCII("delayed_install"); |
| 399 ExtensionSystem* extension_system = extensions::ExtensionSystem::Get( | 400 ExtensionSystem* extension_system = extensions::ExtensionSystem::Get( |
| 400 browser()->profile()); | 401 browser()->profile()); |
| 401 ExtensionService* service = extension_system->extension_service(); | 402 ExtensionService* service = extension_system->extension_service(); |
| 402 ASSERT_TRUE(service); | 403 ASSERT_TRUE(service); |
| 404 ExtensionRegistry* registry = ExtensionRegistry::Get( |
| 405 browser()->profile()); |
| 406 ASSERT_TRUE(registry); |
| 403 | 407 |
| 404 // Install version 1 of the test extension. This extension does not have | 408 // Install version 1 of the test extension. This extension does not have |
| 405 // a background page but does have a browser action. | 409 // a background page but does have a browser action. |
| 406 ASSERT_TRUE(InstallExtension(crx_path.AppendASCII("v1.crx"), 1)); | 410 ASSERT_TRUE(InstallExtension(crx_path.AppendASCII("v1.crx"), 1)); |
| 407 const extensions::Extension* extension = | 411 const extensions::Extension* extension = |
| 408 service->GetExtensionById(extension_id, false); | 412 registry->enabled_extensions().GetByID(extension_id); |
| 409 ASSERT_TRUE(extension); | 413 ASSERT_TRUE(extension); |
| 410 ASSERT_EQ(extension_id, extension->id()); | 414 ASSERT_EQ(extension_id, extension->id()); |
| 411 ASSERT_EQ("1.0", extension->version()->GetString()); | 415 ASSERT_EQ("1.0", extension->version()->GetString()); |
| 412 | 416 |
| 413 // Make test extension non-idle by opening the extension's browser action | 417 // Make test extension non-idle by opening the extension's browser action |
| 414 // popup. This should cause the installation to be delayed. | 418 // popup. This should cause the installation to be delayed. |
| 415 content::WindowedNotificationObserver loading_observer( | 419 content::WindowedNotificationObserver loading_observer( |
| 416 extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, | 420 extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, |
| 417 content::Source<Profile>(profile())); | 421 content::Source<Profile>(profile())); |
| 418 BrowserActionTestUtil util(browser()); | 422 BrowserActionTestUtil util(browser()); |
| 419 // There is only one extension, so just click the first browser action. | 423 // There is only one extension, so just click the first browser action. |
| 420 ASSERT_EQ(1, util.NumberOfBrowserActions()); | 424 ASSERT_EQ(1, util.NumberOfBrowserActions()); |
| 421 util.Press(0); | 425 util.Press(0); |
| 422 loading_observer.Wait(); | 426 loading_observer.Wait(); |
| 423 ExtensionHost* extension_host = | 427 ExtensionHost* extension_host = |
| 424 content::Details<ExtensionHost>(loading_observer.details()).ptr(); | 428 content::Details<ExtensionHost>(loading_observer.details()).ptr(); |
| 425 | 429 |
| 426 // Install version 2 of the extension and check that it is indeed delayed. | 430 // Install version 2 of the extension and check that it is indeed delayed. |
| 427 ASSERT_TRUE(UpdateExtensionWaitForIdle( | 431 ASSERT_TRUE(UpdateExtensionWaitForIdle( |
| 428 extension_id, crx_path.AppendASCII("v2.crx"), 0)); | 432 extension_id, crx_path.AppendASCII("v2.crx"), 0)); |
| 429 | 433 |
| 430 ASSERT_EQ(1u, service->delayed_installs()->size()); | 434 ASSERT_EQ(1u, service->delayed_installs()->size()); |
| 431 extension = service->GetExtensionById(extension_id, false); | 435 extension = registry->enabled_extensions().GetByID(extension_id); |
| 432 ASSERT_EQ("1.0", extension->version()->GetString()); | 436 ASSERT_EQ("1.0", extension->version()->GetString()); |
| 433 | 437 |
| 434 // Make the extension idle again by closing the popup. This should not trigger | 438 // Make the extension idle again by closing the popup. This should not trigger |
| 435 // the delayed install. | 439 // the delayed install. |
| 436 content::RenderProcessHostWatcher terminated_observer( | 440 content::RenderProcessHostWatcher terminated_observer( |
| 437 extension_host->render_process_host(), | 441 extension_host->render_process_host(), |
| 438 content::RenderProcessHostWatcher::WATCH_FOR_HOST_DESTRUCTION); | 442 content::RenderProcessHostWatcher::WATCH_FOR_HOST_DESTRUCTION); |
| 439 extension_host->render_view_host()->ClosePage(); | 443 extension_host->render_view_host()->ClosePage(); |
| 440 terminated_observer.Wait(); | 444 terminated_observer.Wait(); |
| 441 ASSERT_EQ(1u, service->delayed_installs()->size()); | 445 ASSERT_EQ(1u, service->delayed_installs()->size()); |
| 442 | 446 |
| 443 // Install version 3 of the extension. Because the extension is idle, | 447 // Install version 3 of the extension. Because the extension is idle, |
| 444 // this install should succeed. | 448 // this install should succeed. |
| 445 ASSERT_TRUE(UpdateExtensionWaitForIdle( | 449 ASSERT_TRUE(UpdateExtensionWaitForIdle( |
| 446 extension_id, crx_path.AppendASCII("v3.crx"), 0)); | 450 extension_id, crx_path.AppendASCII("v3.crx"), 0)); |
| 447 extension = service->GetExtensionById(extension_id, false); | 451 extension = registry->enabled_extensions().GetByID(extension_id); |
| 448 ASSERT_EQ("3.0", extension->version()->GetString()); | 452 ASSERT_EQ("3.0", extension->version()->GetString()); |
| 449 | 453 |
| 450 // The version 2 delayed install should be cleaned up, and finishing | 454 // The version 2 delayed install should be cleaned up, and finishing |
| 451 // delayed extension installation shouldn't break anything. | 455 // delayed extension installation shouldn't break anything. |
| 452 ASSERT_EQ(0u, service->delayed_installs()->size()); | 456 ASSERT_EQ(0u, service->delayed_installs()->size()); |
| 453 service->MaybeFinishDelayedInstallations(); | 457 service->MaybeFinishDelayedInstallations(); |
| 454 extension = service->GetExtensionById(extension_id, false); | 458 extension = registry->enabled_extensions().GetByID(extension_id); |
| 455 ASSERT_EQ("3.0", extension->version()->GetString()); | 459 ASSERT_EQ("3.0", extension->version()->GetString()); |
| 456 } | 460 } |
| 457 | 461 |
| 458 #if defined(FULL_SAFE_BROWSING) | 462 #if defined(FULL_SAFE_BROWSING) |
| 459 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, Blacklist) { | 463 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, Blacklist) { |
| 460 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db( | 464 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db( |
| 461 new FakeSafeBrowsingDatabaseManager(true)); | 465 new FakeSafeBrowsingDatabaseManager(true)); |
| 462 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db); | 466 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db); |
| 463 | 467 |
| 464 blacklist_db->SetUnsafe("gllekhaobjnhgeagipipnkpmmmpchacm"); | 468 blacklist_db->SetUnsafe("gllekhaobjnhgeagipipnkpmmmpchacm"); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 | 519 |
| 516 base::FilePath crx_path = test_data_dir_.AppendASCII("crx_installer/v1.crx"); | 520 base::FilePath crx_path = test_data_dir_.AppendASCII("crx_installer/v1.crx"); |
| 517 const extensions::Extension* extension = InstallExtension( | 521 const extensions::Extension* extension = InstallExtension( |
| 518 crx_path, 1, extensions::Manifest::EXTERNAL_PREF); | 522 crx_path, 1, extensions::Manifest::EXTERNAL_PREF); |
| 519 base::FilePath extension_path = extension->path(); | 523 base::FilePath extension_path = extension->path(); |
| 520 EXPECT_TRUE(cache_dir.path().IsParent(extension_path)); | 524 EXPECT_TRUE(cache_dir.path().IsParent(extension_path)); |
| 521 EXPECT_TRUE(base::PathExists(extension_path)); | 525 EXPECT_TRUE(base::PathExists(extension_path)); |
| 522 | 526 |
| 523 std::string extension_id = extension->id(); | 527 std::string extension_id = extension->id(); |
| 524 UninstallExtension(extension_id); | 528 UninstallExtension(extension_id); |
| 525 ExtensionService* service = extensions::ExtensionSystem::Get( | 529 ExtensionRegistry* registry = ExtensionRegistry::Get( |
| 526 browser()->profile())->extension_service(); | 530 browser()->profile()); |
| 527 EXPECT_FALSE(service->GetExtensionById(extension_id, false)); | 531 EXPECT_FALSE(registry->enabled_extensions().GetByID(extension_id)); |
| 528 | 532 |
| 529 content::RunAllBlockingPoolTasksUntilIdle(); | 533 content::RunAllBlockingPoolTasksUntilIdle(); |
| 530 | 534 |
| 531 EXPECT_FALSE(base::PathExists(extension_path)); | 535 EXPECT_FALSE(base::PathExists(extension_path)); |
| 532 } | 536 } |
| 533 #endif | 537 #endif |
| 534 | 538 |
| 535 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, DoNotSync) { | 539 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, DoNotSync) { |
| 536 ExtensionService* service = extensions::ExtensionSystem::Get( | 540 ExtensionService* service = extensions::ExtensionSystem::Get( |
| 537 browser()->profile())->extension_service(); | 541 browser()->profile())->extension_service(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 552 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, ManagementPolicy) { | 556 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, ManagementPolicy) { |
| 553 ManagementPolicyMock policy; | 557 ManagementPolicyMock policy; |
| 554 extensions::ExtensionSystem::Get(profile()) | 558 extensions::ExtensionSystem::Get(profile()) |
| 555 ->management_policy() | 559 ->management_policy() |
| 556 ->RegisterProvider(&policy); | 560 ->RegisterProvider(&policy); |
| 557 | 561 |
| 558 base::FilePath crx_path = test_data_dir_.AppendASCII("crx_installer/v1.crx"); | 562 base::FilePath crx_path = test_data_dir_.AppendASCII("crx_installer/v1.crx"); |
| 559 EXPECT_FALSE(InstallExtension(crx_path, 0)); | 563 EXPECT_FALSE(InstallExtension(crx_path, 0)); |
| 560 } | 564 } |
| 561 | 565 |
| 566 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, WithheldElevationCheck) { |
| 567 // Enable consent flag and install extension. The <all_hosts> permission will |
| 568 // be withheld. |
| 569 scoped_ptr<FeatureSwitch::ScopedOverride> enable_scripts_switch( |
| 570 new FeatureSwitch::ScopedOverride( |
| 571 FeatureSwitch::scripts_require_action(), true)); |
| 572 |
| 573 const char kManifest[] = |
| 574 "{" |
| 575 " \"name\": \"Withheld test\"," |
| 576 " \"version\": \"1.0\"," |
| 577 " \"permissions\": [" |
| 578 " \"http://*/*\"" |
| 579 " ]," |
| 580 " \"manifest_version\": 2" |
| 581 "}"; |
| 582 TestExtensionDir dir; |
| 583 dir.WriteManifest(kManifest); |
| 584 base::FilePath crx_path = dir.Pack(); |
| 585 EXPECT_FALSE(crx_path.empty()); |
| 586 const Extension* extension = InstallExtension(crx_path, 1); |
| 587 EXPECT_TRUE(base::PathExists(extension->path())); |
| 588 |
| 589 std::string extension_id = extension->id(); |
| 590 ExtensionRegistry* registry = ExtensionRegistry::Get( |
| 591 browser()->profile()); |
| 592 EXPECT_TRUE(registry->enabled_extensions().GetByID(extension_id)); |
| 593 |
| 594 // Disable consent flag and reinstall extension. It should now be disabled |
| 595 // because previously withheld permissions are now being requested. |
| 596 enable_scripts_switch.reset(); |
| 597 extension = InstallExtension(crx_path, -1); |
| 598 EXPECT_FALSE(registry->enabled_extensions().GetByID(extension_id)); |
| 599 EXPECT_TRUE(registry->disabled_extensions().GetByID(extension_id)); |
| 600 EXPECT_TRUE(ExtensionPrefs::Get(browser()->profile())->GetDisableReasons( |
| 601 extension_id) & Extension::DISABLE_PERMISSIONS_INCREASE); |
| 602 } |
| 603 |
| 562 } // namespace extensions | 604 } // namespace extensions |
| OLD | NEW |