diff options
Diffstat (limited to 'chromium/chrome/browser/extensions/api')
158 files changed, 2310 insertions, 3193 deletions
diff --git a/chromium/chrome/browser/extensions/api/OWNERS b/chromium/chrome/browser/extensions/api/OWNERS deleted file mode 100644 index 7eafe922486..00000000000 --- a/chromium/chrome/browser/extensions/api/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# For Chrome OS apps APIs. -tbarzic@chromium.org diff --git a/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc b/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc index 2b44f3e0e6f..49b4da3c607 100644 --- a/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc +++ b/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc @@ -71,6 +71,19 @@ void RemoveDuplicatePhoneNumberAtIndex( list->Remove(index, nullptr); } +autofill::AutofillManager* GetAutofillManager( + content::WebContents* web_contents) { + if (!web_contents) { + return nullptr; + } + autofill::ContentAutofillDriver* autofill_driver = + autofill::ContentAutofillDriverFactory::FromWebContents(web_contents) + ->DriverForFrame(web_contents->GetMainFrame()); + if (!autofill_driver) + return nullptr; + return autofill_driver->autofill_manager(); +} + } // namespace namespace extensions { @@ -111,10 +124,6 @@ ExtensionFunction::ResponseAction AutofillPrivateSaveAddressFunction::Run() { ? *existing_profile : autofill::AutofillProfile(base::GenerateGUID(), kSettingsOrigin); - // Strings from JavaScript use UTF-8 encoding. This container is used as an - // intermediate container for functions which require UTF-16 strings. - std::vector<base::string16> string16Container; - if (address->full_names) { std::string full_name; if (!address->full_names->empty()) @@ -255,7 +264,7 @@ ExtensionFunction::ResponseAction for (auto& component : components->GetList()) { base::Value row(base::Value::Type::DICTIONARY); row.SetKey("row", std::move(component)); - rows.GetList().emplace_back(std::move(row)); + rows.Append(std::move(row)); } address_components.SetKey("components", std::move(rows)); @@ -471,17 +480,13 @@ AutofillPrivateMigrateCreditCardsFunction::Run() { autofill::PersonalDataManager* personal_data = autofill::PersonalDataManagerFactory::GetForProfile( chrome_details_.GetProfile()); - // Get the web contents to get autofill manager. - content::WebContents* web_contents = GetSenderWebContents(); - if (!personal_data || !personal_data->IsDataLoaded() || !web_contents) + if (!personal_data || !personal_data->IsDataLoaded()) return RespondNow(Error(kErrorDataUnavailable)); // Get the AutofillManager from the web contents. AutofillManager has a // pointer to its AutofillClient which owns FormDataImporter. autofill::AutofillManager* autofill_manager = - autofill::ContentAutofillDriverFactory::FromWebContents(web_contents) - ->DriverForFrame(web_contents->GetMainFrame()) - ->autofill_manager(); + GetAutofillManager(GetSenderWebContents()); if (!autofill_manager || !autofill_manager->client()) return RespondNow(Error(kErrorDataUnavailable)); @@ -529,4 +534,36 @@ AutofillPrivateLogServerCardLinkClickedFunction::Run() { return RespondNow(NoArguments()); } +//////////////////////////////////////////////////////////////////////////////// +// AutofillPrivateSetCreditCardFIDOAuthEnabledStateFunction + +AutofillPrivateSetCreditCardFIDOAuthEnabledStateFunction:: + AutofillPrivateSetCreditCardFIDOAuthEnabledStateFunction() + : chrome_details_(this) {} + +AutofillPrivateSetCreditCardFIDOAuthEnabledStateFunction:: + ~AutofillPrivateSetCreditCardFIDOAuthEnabledStateFunction() {} + +ExtensionFunction::ResponseAction +AutofillPrivateSetCreditCardFIDOAuthEnabledStateFunction::Run() { + // Getting CreditCardAccessManager from WebContents. + autofill::AutofillManager* autofill_manager = + GetAutofillManager(GetSenderWebContents()); + if (!autofill_manager) + return RespondNow(Error(kErrorDataUnavailable)); + autofill::CreditCardAccessManager* credit_card_access_manager = + autofill_manager->credit_card_access_manager(); + if (!credit_card_access_manager) + return RespondNow(Error(kErrorDataUnavailable)); + + std::unique_ptr< + api::autofill_private::SetCreditCardFIDOAuthEnabledState::Params> + parameters = api::autofill_private::SetCreditCardFIDOAuthEnabledState:: + Params::Create(*args_); + EXTENSION_FUNCTION_VALIDATE(parameters.get()); + + credit_card_access_manager->OnSettingsPageFIDOAuthToggled( + parameters->enabled); + return RespondNow(NoArguments()); +} } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_api.h b/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_api.h index 5b42cd41d7a..0594f1421d6 100644 --- a/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_api.h +++ b/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_api.h @@ -208,6 +208,27 @@ class AutofillPrivateLogServerCardLinkClickedFunction DISALLOW_COPY_AND_ASSIGN(AutofillPrivateLogServerCardLinkClickedFunction); }; +class AutofillPrivateSetCreditCardFIDOAuthEnabledStateFunction + : public ExtensionFunction { + public: + AutofillPrivateSetCreditCardFIDOAuthEnabledStateFunction(); + DECLARE_EXTENSION_FUNCTION( + "autofillPrivate.setCreditCardFIDOAuthEnabledState", + AUTOFILLPRIVATE_SETCREDITCARDFIDOAUTHENABLEDSTATE) + + protected: + ~AutofillPrivateSetCreditCardFIDOAuthEnabledStateFunction() override; + + // ExtensionFunction overrides. + ResponseAction Run() override; + + private: + ChromeExtensionFunctionDetails chrome_details_; + + DISALLOW_COPY_AND_ASSIGN( + AutofillPrivateSetCreditCardFIDOAuthEnabledStateFunction); +}; + } // namespace extensions #endif // CHROME_BROWSER_EXTENSIONS_API_AUTOFILL_PRIVATE_AUTOFILL_PRIVATE_API_H_ diff --git a/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_event_router.cc b/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_event_router.cc index c90d6a5f45a..dc419d22ac6 100644 --- a/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_event_router.cc +++ b/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_event_router.cc @@ -50,7 +50,6 @@ void AutofillPrivateEventRouter::Shutdown() { personal_data_->RemoveObserver(this); } -// TODO(crbug.com/923868): Change the 2 calls to a single OnPersonalDataChanged. void AutofillPrivateEventRouter::OnPersonalDataChanged() { // Ignore any updates before data is loaded. This can happen in tests. if (!(personal_data_ && personal_data_->IsDataLoaded())) @@ -58,24 +57,20 @@ void AutofillPrivateEventRouter::OnPersonalDataChanged() { autofill_util::AddressEntryList addressList = extensions::autofill_util::GenerateAddressList(*personal_data_); - std::unique_ptr<base::ListValue> args( - api::autofill_private::OnAddressListChanged::Create(addressList) - .release()); - std::unique_ptr<Event> extension_event( - new Event(events::AUTOFILL_PRIVATE_ON_ADDRESS_LIST_CHANGED, - api::autofill_private::OnAddressListChanged::kEventName, - std::move(args))); - event_router_->BroadcastEvent(std::move(extension_event)); autofill_util::CreditCardEntryList creditCardList = extensions::autofill_util::GenerateCreditCardList(*personal_data_); - args.reset( - api::autofill_private::OnCreditCardListChanged::Create(creditCardList) + + std::unique_ptr<base::ListValue> args( + api::autofill_private::OnPersonalDataChanged::Create(addressList, + creditCardList) .release()); - extension_event.reset( - new Event(events::AUTOFILL_PRIVATE_ON_CREDIT_CARD_LIST_CHANGED, - api::autofill_private::OnCreditCardListChanged::kEventName, + + std::unique_ptr<Event> extension_event( + new Event(events::AUTOFILL_PRIVATE_ON_PERSONAL_DATA_CHANGED, + api::autofill_private::OnPersonalDataChanged::kEventName, std::move(args))); + event_router_->BroadcastEvent(std::move(extension_event)); } diff --git a/chromium/chrome/browser/extensions/api/automation/automation_apitest.cc b/chromium/chrome/browser/extensions/api/automation/automation_apitest.cc index bca9fda86c7..fbea761097b 100644 --- a/chromium/chrome/browser/extensions/api/automation/automation_apitest.cc +++ b/chromium/chrome/browser/extensions/api/automation/automation_apitest.cc @@ -16,7 +16,6 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/extensions/chrome_extension_messages.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/ui_test_utils.h" #include "components/prefs/pref_service.h" @@ -414,6 +413,13 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTestWithLanguageDetection, << message_; } +IN_PROC_BROWSER_TEST_F(AutomationApiTest, IgnoredNodesNotReturned) { + StartEmbeddedTestServer(); + ASSERT_TRUE(RunExtensionSubtest("automation/tests/tabs", + "ignored_nodes_not_returned.html")) + << message_; +} + #if defined(OS_CHROMEOS) class AutomationApiTestWithDeviceScaleFactor : public AutomationApiTest { diff --git a/chromium/chrome/browser/extensions/api/automation_internal/chrome_automation_internal_api_delegate.cc b/chromium/chrome/browser/extensions/api/automation_internal/chrome_automation_internal_api_delegate.cc index f2333134976..ceb98f41dde 100644 --- a/chromium/chrome/browser/extensions/api/automation_internal/chrome_automation_internal_api_delegate.cc +++ b/chromium/chrome/browser/extensions/api/automation_internal/chrome_automation_internal_api_delegate.cc @@ -13,7 +13,6 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/extensions/chrome_extension_messages.h" #include "content/public/browser/web_contents.h" #include "extensions/common/api/automation.h" #include "extensions/common/api/automation_internal.h" diff --git a/chromium/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc b/chromium/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc index 97b4ffd67fa..13886741894 100644 --- a/chromium/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc +++ b/chromium/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc @@ -39,19 +39,14 @@ class BluetoothLowEnergyApiTestChromeOs : public PlatformAppBrowserTest { } void TearDownOnMainThread() override { - PlatformAppBrowserTest::TearDownOnMainThread(); + owner_settings_service_.reset(); settings_helper_.RestoreRealDeviceSettingsProvider(); + PlatformAppBrowserTest::TearDownOnMainThread(); user_manager_enabler_.reset(); fake_user_manager_ = nullptr; } protected: - chromeos::FakeChromeUserManager* fake_user_manager_; - std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_; - - chromeos::ScopedCrosSettingsTestHelper settings_helper_; - std::unique_ptr<chromeos::FakeOwnerSettingsService> owner_settings_service_; - void EnterKioskSession() { fake_user_manager_ = new chromeos::FakeChromeUserManager(); user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>( @@ -72,6 +67,12 @@ class BluetoothLowEnergyApiTestChromeOs : public PlatformAppBrowserTest { chromeos::KioskAppManager* manager() const { return chromeos::KioskAppManager::Get(); } + + chromeos::FakeChromeUserManager* fake_user_manager_; + std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_; + + chromeos::ScopedCrosSettingsTestHelper settings_helper_; + std::unique_ptr<chromeos::FakeOwnerSettingsService> owner_settings_service_; }; IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTestChromeOs, diff --git a/chromium/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc b/chromium/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc index 42aa452c796..d0c59bb4cc4 100644 --- a/chromium/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc +++ b/chromium/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc @@ -55,6 +55,7 @@ namespace extensions { namespace bookmark_keys = bookmark_api_constants; namespace bookmark_manager_private = api::bookmark_manager_private; +namespace CanPaste = api::bookmark_manager_private::CanPaste; namespace Copy = api::bookmark_manager_private::Copy; namespace Cut = api::bookmark_manager_private::Cut; namespace Drop = api::bookmark_manager_private::Drop; @@ -161,6 +162,14 @@ bookmark_manager_private::BookmarkNodeData CreateApiBookmarkNodeData( return node_data; } +bool HasPermanentNodes(const std::vector<const BookmarkNode*>& list) { + for (const BookmarkNode* node : list) { + if (node->is_permanent_node()) + return true; + } + return false; +} + } // namespace BookmarkManagerPrivateEventRouter::BookmarkManagerPrivateEventRouter( @@ -315,6 +324,10 @@ bool ClipboardBookmarkManagerFunction::CopyOrCut(bool cut, error_ = bookmark_keys::kModifyManagedError; return false; } + if (cut && HasPermanentNodes(nodes)) { + error_ = bookmark_keys::kModifySpecialError; + return false; + } bookmarks::CopyToClipboard(model, nodes, cut); return true; } @@ -369,6 +382,28 @@ bool BookmarkManagerPrivatePasteFunction::RunOnReady() { return true; } +bool BookmarkManagerPrivateCanPasteFunction::RunOnReady() { + std::unique_ptr<CanPaste::Params> params(CanPaste::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params); + + PrefService* prefs = user_prefs::UserPrefs::Get(GetProfile()); + if (!prefs->GetBoolean(bookmarks::prefs::kEditBookmarksEnabled)) { + SetResult(std::make_unique<base::Value>(false)); + return true; + } + + BookmarkModel* model = + BookmarkModelFactory::GetForBrowserContext(GetProfile()); + const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id); + if (!parent_node) { + error_ = bookmark_keys::kNoParentError; + return false; + } + bool can_paste = bookmarks::CanPasteFromClipboard(model, parent_node); + SetResult(std::make_unique<base::Value>(can_paste)); + return true; +} + bool BookmarkManagerPrivateSortChildrenFunction::RunOnReady() { if (!EditBookmarksEnabled()) return false; diff --git a/chromium/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h b/chromium/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h index b73ca175c0d..c85dd537d4c 100644 --- a/chromium/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h +++ b/chromium/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h @@ -173,6 +173,19 @@ class BookmarkManagerPrivatePasteFunction bool RunOnReady() override; }; +class BookmarkManagerPrivateCanPasteFunction + : public extensions::BookmarksFunction { + public: + DECLARE_EXTENSION_FUNCTION("bookmarkManagerPrivate.canPaste", + BOOKMARKMANAGERPRIVATE_CANPASTE) + + protected: + ~BookmarkManagerPrivateCanPasteFunction() override {} + + // ExtensionFunction: + bool RunOnReady() override; +}; + class BookmarkManagerPrivateSortChildrenFunction : public extensions::BookmarksFunction { public: diff --git a/chromium/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api_unittest.cc b/chromium/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api_unittest.cc index b5099b06a09..199416715d5 100644 --- a/chromium/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api_unittest.cc +++ b/chromium/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api_unittest.cc @@ -4,6 +4,7 @@ #include "chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h" +#include "base/memory/scoped_refptr.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" @@ -33,6 +34,7 @@ class BookmarkManagerPrivateApiUnitTest : public ExtensionServiceTestBase { node_id_ = base::NumberToString(node->id()); } + const bookmarks::BookmarkModel* model() const { return model_; } std::string node_id() const { return node_id_; } private: @@ -47,15 +49,14 @@ class BookmarkManagerPrivateApiUnitTest : public ExtensionServiceTestBase { // Regression test for https://crbug.com/739260. TEST_F(BookmarkManagerPrivateApiUnitTest, RunOnDeletedNode) { // Remove our only bookmark node. - scoped_refptr<BookmarksRemoveFunction> remove_function( - new BookmarksRemoveFunction()); + auto remove_function = base::MakeRefCounted<BookmarksRemoveFunction>(); api_test_utils::RunFunction(remove_function.get(), base::StringPrintf("[\"%s\"]", node_id().c_str()), profile()); // Call bookmarkManagerPrivate.copy() with the removed bookmark node's id. - scoped_refptr<BookmarkManagerPrivateCopyFunction> copy_function( - new BookmarkManagerPrivateCopyFunction()); + auto copy_function = + base::MakeRefCounted<BookmarkManagerPrivateCopyFunction>(); EXPECT_EQ( "Could not find bookmark nodes with given ids.", api_test_utils::RunFunctionAndReturnError( @@ -63,4 +64,17 @@ TEST_F(BookmarkManagerPrivateApiUnitTest, RunOnDeletedNode) { base::StringPrintf("[[\"%s\"]]", node_id().c_str()), profile())); } +// Tests that calling bookmarkManagerPrivate.cut() to cut a permanent bookmark +// node into the clipboard gracefully fails. +// Regression test for https://crbug.com/1021829. +TEST_F(BookmarkManagerPrivateApiUnitTest, RunCutOnPermanentNode) { + auto cut_function = base::MakeRefCounted<BookmarkManagerPrivateCutFunction>(); + std::string node_id = + base::NumberToString(model()->bookmark_bar_node()->id()); + EXPECT_EQ("Can't modify the root bookmark folders.", + api_test_utils::RunFunctionAndReturnError( + cut_function.get(), + base::StringPrintf("[[\"%s\"]]", node_id.c_str()), profile())); +} + } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc b/chromium/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc index 12113c4f5d4..e3cebde37c3 100644 --- a/chromium/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc +++ b/chromium/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc @@ -182,10 +182,9 @@ const BookmarkNode* BookmarksFunction::CreateBookmarkNode( const BookmarkNode* node; if (url_string.length()) { - node = model->AddURLWithCreationTimeAndMetaInfo( - parent, index, title, url, base::Time::Now(), meta_info); + node = model->AddURL(parent, index, title, url, meta_info); } else { - node = model->AddFolderWithMetaInfo(parent, index, title, meta_info); + node = model->AddFolder(parent, index, title, meta_info); model->SetDateFolderModified(parent, base::Time::Now()); } diff --git a/chromium/chrome/browser/extensions/api/braille_display_private/braille_controller_brlapi.cc b/chromium/chrome/browser/extensions/api/braille_display_private/braille_controller_brlapi.cc index 09b44ef1f9a..f21ccfe51bc 100644 --- a/chromium/chrome/browser/extensions/api/braille_display_private/braille_controller_brlapi.cc +++ b/chromium/chrome/browser/extensions/api/braille_display_private/braille_controller_brlapi.cc @@ -78,9 +78,7 @@ void BrailleControllerImpl::TryLoadLibBrlApi() { // These versions of libbrlapi work the same for the functions we // are using. (0.6.0 adds brlapi_writeWText). static const char* const kSupportedVersions[] = { - "libbrlapi.so.0.5", - "libbrlapi.so.0.6" - }; + "libbrlapi.so.0.5", "libbrlapi.so.0.6", "libbrlapi.so.0.7"}; for (size_t i = 0; i < base::size(kSupportedVersions); ++i) { if (libbrlapi_loader_.Load(kSupportedVersions[i])) return; diff --git a/chromium/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc b/chromium/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc index b2e4c22d486..04622a3e005 100644 --- a/chromium/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc +++ b/chromium/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc @@ -49,12 +49,13 @@ const char kRemoveEverythingArguments[] = "webSQL": true }])"; -// Sets the APISID Gaia cookie, which is monitored by the AccountReconcilor. +// Sets the SAPISID Gaia cookie, which is monitored by the AccountReconcilor. bool SetGaiaCookieForProfile(Profile* profile) { - GURL google_url = GaiaUrls::GetInstance()->google_url(); - net::CanonicalCookie cookie("APISID", std::string(), "." + google_url.host(), + GURL google_url = GaiaUrls::GetInstance()->secure_google_url(); + net::CanonicalCookie cookie("SAPISID", std::string(), "." + google_url.host(), "/", base::Time(), base::Time(), base::Time(), - false, false, net::CookieSameSite::NO_RESTRICTION, + /*secure=*/true, false, + net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_DEFAULT); bool success = false; @@ -70,10 +71,8 @@ bool SetGaiaCookieForProfile(Profile* profile) { network::mojom::CookieManager* cookie_manager = content::BrowserContext::GetDefaultStoragePartition(profile) ->GetCookieManagerForBrowserProcess(); - net::CookieOptions options; - options.set_include_httponly(); cookie_manager->SetCanonicalCookie( - cookie, google_url.scheme(), options, + cookie, google_url.scheme(), net::CookieOptions::MakeAllInclusive(), mojo::WrapCallbackWithDefaultInvokeIfNotRun( std::move(callback), net::CanonicalCookie::CookieInclusionStatus( net::CanonicalCookie::CookieInclusionStatus:: @@ -106,7 +105,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowsingDataTest, Syncing) { syncer::SyncService* sync_service = ProfileSyncServiceFactory::GetForProfile(profile); sync_service->GetUserSettings()->SetSyncRequested(true); - sync_service->GetUserSettings()->SetFirstSetupComplete(); + sync_service->GetUserSettings()->SetFirstSetupComplete( + syncer::SyncFirstSetupCompleteSource::BASIC_FLOW); ASSERT_EQ(sync_ui_util::SYNCED, sync_ui_util::GetStatus(profile)); // Clear browsing data. diff --git a/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc b/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc index 533bdee1e87..4530f54ea05 100644 --- a/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc +++ b/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc @@ -12,6 +12,8 @@ #include "base/bind.h" #include "base/logging.h" +#include "base/macros.h" +#include "base/values.h" #include "chrome/browser/chromeos/certificate_provider/certificate_provider_service.h" #include "chrome/browser/chromeos/certificate_provider/certificate_provider_service_factory.h" #include "chrome/browser/chromeos/certificate_provider/pin_dialog_manager.h" @@ -19,6 +21,7 @@ #include "chrome/common/extensions/api/certificate_provider.h" #include "chrome/common/extensions/api/certificate_provider_internal.h" #include "chromeos/constants/security_token_pin_types.h" +#include "extensions/browser/quota_service.h" #include "net/cert/x509_certificate.h" #include "net/ssl/ssl_private_key.h" #include "third_party/blink/public/mojom/devtools/console_message.mojom.h" @@ -75,9 +78,55 @@ const char kCertificateProviderPreviousDialogActive[] = "Previous request not finished"; const char kCertificateProviderNoUserInput[] = "No user input received"; +// The BucketMapper implementation for the requestPin API that avoids using the +// quota when the current request uses the requestId that is strictly greater +// than all previous ones. +class RequestPinExceptFirstQuotaBucketMapper final + : public QuotaLimitHeuristic::BucketMapper { + public: + RequestPinExceptFirstQuotaBucketMapper() = default; + ~RequestPinExceptFirstQuotaBucketMapper() override = default; + + void GetBucketsForArgs(const base::ListValue* args, + QuotaLimitHeuristic::BucketList* buckets) override { + if (args->GetList().empty()) + return; + const base::Value& details = args->GetList()[0]; + if (!details.is_dict()) + return; + const base::Value* sign_request_id = + details.FindKeyOfType("signRequestId", base::Value::Type::INTEGER); + if (!sign_request_id) + return; + if (sign_request_id->GetInt() > biggest_request_id_) { + // Either it's the first request with the newly issued requestId, or it's + // an invalid requestId (bigger than the real one). Return a new bucket in + // order to apply no quota for the former case; for the latter case the + // quota doesn't matter much, except that we're maybe making it stricter + // for future requests (which is bearable). + biggest_request_id_ = sign_request_id->GetInt(); + new_request_bucket_ = std::make_unique<QuotaLimitHeuristic::Bucket>(); + buckets->push_back(new_request_bucket_.get()); + return; + } + // Either it's a repeatitive request for the given requestId, or the + // extension reordered the requests. Fall back to the default bucket (shared + // between all requests) in that case. + buckets->push_back(&default_bucket_); + } + + private: + int biggest_request_id_ = -1; + QuotaLimitHeuristic::Bucket default_bucket_; + std::unique_ptr<QuotaLimitHeuristic::Bucket> new_request_bucket_; + + DISALLOW_COPY_AND_ASSIGN(RequestPinExceptFirstQuotaBucketMapper); +}; + } // namespace -const int api::certificate_provider::kMaxClosedDialogsPer10Mins = 2; +const int api::certificate_provider::kMaxClosedDialogsPerMinute = 10; +const int api::certificate_provider::kMaxClosedDialogsPer10Minutes = 30; CertificateProviderInternalReportCertificatesFunction:: ~CertificateProviderInternalReportCertificatesFunction() {} @@ -256,12 +305,25 @@ bool CertificateProviderRequestPinFunction::ShouldSkipQuotaLimiting() const { } void CertificateProviderRequestPinFunction::GetQuotaLimitHeuristics( - extensions::QuotaLimitHeuristics* heuristics) const { + QuotaLimitHeuristics* heuristics) const { + // Apply a 1-minute and a 10-minute quotas. A special bucket mapper is used in + // order to, approximately, skip applying quotas to the first request for each + // requestId (such logic cannot be done in ShouldSkipQuotaLimiting(), since + // it's not called with the request's parameters). The limitation constants + // are decremented below to account the first request. + QuotaLimitHeuristic::Config short_limit_config = { - api::certificate_provider::kMaxClosedDialogsPer10Mins, + api::certificate_provider::kMaxClosedDialogsPerMinute - 1, + base::TimeDelta::FromMinutes(1)}; + heuristics->push_back(std::make_unique<QuotaService::TimedLimit>( + short_limit_config, new RequestPinExceptFirstQuotaBucketMapper, + "MAX_PIN_DIALOGS_CLOSED_PER_MINUTE")); + + QuotaLimitHeuristic::Config long_limit_config = { + api::certificate_provider::kMaxClosedDialogsPer10Minutes - 1, base::TimeDelta::FromMinutes(10)}; heuristics->push_back(std::make_unique<QuotaService::TimedLimit>( - short_limit_config, new QuotaLimitHeuristic::SingletonBucketMapper(), + long_limit_config, new RequestPinExceptFirstQuotaBucketMapper, "MAX_PIN_DIALOGS_CLOSED_PER_10_MINUTES")); } diff --git a/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.h b/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.h index b61e947336d..623b666b35d 100644 --- a/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.h +++ b/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.h @@ -19,9 +19,10 @@ namespace extensions { namespace api { namespace certificate_provider { -// The maximum number of times per 10 minutes, extension is allowed to show PIN -// dialog again after user closed the previous one. -extern const int kMaxClosedDialogsPer10Mins; +// The maximum number of times in the given interval the extension is allowed to +// show the PIN dialog again after user closed the previous one. +extern const int kMaxClosedDialogsPerMinute; +extern const int kMaxClosedDialogsPer10Minutes; struct CertificateInfo; } diff --git a/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc b/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc index 1611eb4a730..1de2320a536 100644 --- a/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc +++ b/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc @@ -171,9 +171,9 @@ class CertificateProviderRequestPinTest : public CertificateProviderApiTest { CertificateProviderApiTest::TearDownOnMainThread(); } - void AddFakeSignRequest() { + void AddFakeSignRequest(int sign_request_id) { cert_provider_service_->pin_dialog_manager()->AddSignRequestId( - extension_->id(), kFakeSignRequestId, {}); + extension_->id(), sign_request_id, {}); } void NavigateTo(const std::string& test_page_file_name) { @@ -372,7 +372,7 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderApiTest, Basic) { // User enters the correct PIN. IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, ShowPinDialogAccept) { - AddFakeSignRequest(); + AddFakeSignRequest(kFakeSignRequestId); NavigateTo("basic.html"); // Enter the valid PIN. @@ -382,14 +382,14 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, ShowPinDialogAccept) { EXPECT_FALSE(GetActivePinDialogView()); } -// User closes the dialog kMaxClosedDialogsPer10Mins times, and the extension +// User closes the dialog kMaxClosedDialogsPerMinute times, and the extension // should be blocked from showing it again. IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, ShowPinDialogClose) { - AddFakeSignRequest(); + AddFakeSignRequest(kFakeSignRequestId); NavigateTo("basic.html"); for (int i = 0; - i < extensions::api::certificate_provider::kMaxClosedDialogsPer10Mins; + i < extensions::api::certificate_provider::kMaxClosedDialogsPerMinute; i++) { ExtensionTestMessageListener listener("User closed the dialog", false); GetActivePinDialogWindow()->Close(); @@ -401,7 +401,7 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, ShowPinDialogClose) { ASSERT_TRUE(close_listener.WaitUntilSatisfied()); close_listener.Reply("GetLastError"); ExtensionTestMessageListener last_error_listener( - "This request exceeds the MAX_PIN_DIALOGS_CLOSED_PER_10_MINUTES quota.", + "This request exceeds the MAX_PIN_DIALOGS_CLOSED_PER_MINUTE quota.", false); ASSERT_TRUE(last_error_listener.WaitUntilSatisfied()); EXPECT_FALSE(GetActivePinDialogView()); @@ -410,7 +410,7 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, ShowPinDialogClose) { // User enters a wrong PIN first and a correct PIN on the second try. IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, ShowPinDialogWrongPin) { - AddFakeSignRequest(); + AddFakeSignRequest(kFakeSignRequestId); NavigateTo("basic.html"); EnterWrongPinAndWaitForMessage(); @@ -428,7 +428,7 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, // User enters wrong PIN three times. IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, ShowPinDialogWrongPinThreeTimes) { - AddFakeSignRequest(); + AddFakeSignRequest(kFakeSignRequestId); NavigateTo("basic.html"); for (int i = 0; i < kWrongPinAttemptsLimit; i++) EnterWrongPinAndWaitForMessage(); @@ -446,7 +446,7 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, // User closes the dialog while the extension is processing the request. IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, ShowPinDialogCloseWhileProcessing) { - AddFakeSignRequest(); + AddFakeSignRequest(kFakeSignRequestId); NavigateTo("operated.html"); EXPECT_TRUE(SendCommandAndWaitForMessage("Request", "request1:begun")); @@ -462,7 +462,7 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, EXPECT_FALSE(GetActivePinDialogView()); } -// Extension closes the dialog kMaxClosedDialogsPer10Mins times after the user +// Extension closes the dialog kMaxClosedDialogsPerMinute times after the user // inputs some value, and it should be blocked from showing it again. IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, RepeatedProgrammaticCloseAfterInput) { @@ -470,9 +470,9 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, for (int i = 0; i < - extensions::api::certificate_provider::kMaxClosedDialogsPer10Mins + 1; + extensions::api::certificate_provider::kMaxClosedDialogsPerMinute + 1; i++) { - AddFakeSignRequest(); + AddFakeSignRequest(kFakeSignRequestId); EXPECT_TRUE(SendCommandAndWaitForMessage( "Request", base::StringPrintf("request%d:begun", i + 1))); @@ -482,20 +482,20 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, EXPECT_FALSE(GetActivePinDialogView()); } - AddFakeSignRequest(); + AddFakeSignRequest(kFakeSignRequestId); EXPECT_TRUE(SendCommandAndWaitForMessage( "Request", base::StringPrintf( "request%d:error:This request exceeds the " - "MAX_PIN_DIALOGS_CLOSED_PER_10_MINUTES quota.", - extensions::api::certificate_provider::kMaxClosedDialogsPer10Mins + + "MAX_PIN_DIALOGS_CLOSED_PER_MINUTE quota.", + extensions::api::certificate_provider::kMaxClosedDialogsPerMinute + 2))); EXPECT_FALSE(GetActivePinDialogView()); } // Extension erroneously attempts to close the PIN dialog twice. IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, DoubleClose) { - AddFakeSignRequest(); + AddFakeSignRequest(kFakeSignRequestId); NavigateTo("operated.html"); EXPECT_TRUE(SendCommand("Request")); @@ -505,7 +505,7 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, DoubleClose) { EXPECT_FALSE(GetActivePinDialogView()); } -// Extension closes the dialog kMaxClosedDialogsPer10Mins times before the user +// Extension closes the dialog kMaxClosedDialogsPerMinute times before the user // inputs anything, and it should be blocked from showing it again. IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, RepeatedProgrammaticCloseBeforeInput) { @@ -513,22 +513,22 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, for (int i = 0; i < - extensions::api::certificate_provider::kMaxClosedDialogsPer10Mins + 1; + extensions::api::certificate_provider::kMaxClosedDialogsPerMinute + 1; i++) { - AddFakeSignRequest(); + AddFakeSignRequest(kFakeSignRequestId); EXPECT_TRUE(SendCommand("Request")); EXPECT_TRUE(SendCommandAndWaitForMessage( "Stop", base::StringPrintf("stop%d:success", i + 1))); EXPECT_FALSE(GetActivePinDialogView()); } - AddFakeSignRequest(); + AddFakeSignRequest(kFakeSignRequestId); EXPECT_TRUE(SendCommandAndWaitForMessage( "Request", base::StringPrintf( "request%d:error:This request exceeds the " - "MAX_PIN_DIALOGS_CLOSED_PER_10_MINUTES quota.", - extensions::api::certificate_provider::kMaxClosedDialogsPer10Mins + + "MAX_PIN_DIALOGS_CLOSED_PER_MINUTE quota.", + extensions::api::certificate_provider::kMaxClosedDialogsPerMinute + 2))); EXPECT_FALSE(GetActivePinDialogView()); } @@ -537,7 +537,7 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, // the user provided any input. IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, StopWithErrorBeforeInput) { - AddFakeSignRequest(); + AddFakeSignRequest(kFakeSignRequestId); NavigateTo("operated.html"); EXPECT_TRUE(SendCommand("Request")); @@ -557,7 +557,7 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, InvalidRequestId) { // Extension specifies zero left attempts in the very first PIN request. IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, ZeroAttemptsAtStart) { - AddFakeSignRequest(); + AddFakeSignRequest(kFakeSignRequestId); NavigateTo("operated.html"); EXPECT_TRUE(SendCommandAndWaitForMessage("RequestWithZeroAttempts", @@ -573,7 +573,7 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, ZeroAttemptsAtStart) { // Extension erroneously passes a negative attempts left count. IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, NegativeAttempts) { - AddFakeSignRequest(); + AddFakeSignRequest(kFakeSignRequestId); NavigateTo("operated.html"); EXPECT_TRUE(SendCommandAndWaitForMessage( @@ -583,7 +583,7 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, NegativeAttempts) { // Extension erroneously attempts to close a non-existing dialog. IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, CloseNonExisting) { - AddFakeSignRequest(); + AddFakeSignRequest(kFakeSignRequestId); NavigateTo("operated.html"); EXPECT_TRUE(SendCommandAndWaitForMessage( @@ -593,7 +593,7 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, CloseNonExisting) { // Extension erroneously attempts to stop a non-existing dialog with an error. IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, StopNonExisting) { - AddFakeSignRequest(); + AddFakeSignRequest(kFakeSignRequestId); NavigateTo("operated.html"); EXPECT_TRUE(SendCommandAndWaitForMessage( @@ -605,7 +605,7 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, StopNonExisting) { // user closed the previously stopped with an error PIN request. IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, UpdateAlreadyStopped) { - AddFakeSignRequest(); + AddFakeSignRequest(kFakeSignRequestId); NavigateTo("operated.html"); EXPECT_TRUE(SendCommandAndWaitForMessage("Request", "request1:begun")); @@ -622,7 +622,7 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, // Extension starts a new PIN request after it stopped the previous one with an // error. IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, StartAfterStop) { - AddFakeSignRequest(); + AddFakeSignRequest(kFakeSignRequestId); NavigateTo("operated.html"); EXPECT_TRUE(SendCommandAndWaitForMessage("Request", "request1:begun")); @@ -637,3 +637,28 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, StartAfterStop) { EXPECT_TRUE(listener.WaitUntilSatisfied()); EXPECT_FALSE(GetActivePinDialogView()->textfield_for_testing()->GetEnabled()); } + +// Test that no quota is applied to the first PIN requests for each requestId. +IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, + RepeatedCloseWithDifferentIds) { + NavigateTo("operated.html"); + + for (int i = 0; + i < + extensions::api::certificate_provider::kMaxClosedDialogsPer10Minutes + 2; + i++) { + AddFakeSignRequest(kFakeSignRequestId + i); + EXPECT_TRUE(SendCommandAndWaitForMessage( + "Request", base::StringPrintf("request%d:begun", i + 1))); + + ExtensionTestMessageListener listener( + base::StringPrintf("request%d:empty", i + 1), false); + ASSERT_TRUE(GetActivePinDialogView()); + GetActivePinDialogView()->GetWidget()->CloseWithReason( + views::Widget::ClosedReason::kCloseButtonClicked); + EXPECT_TRUE(listener.WaitUntilSatisfied()); + EXPECT_FALSE(GetActivePinDialogView()); + + EXPECT_TRUE(SendCommand("IncrementRequestId")); + } +} diff --git a/chromium/chrome/browser/extensions/api/chrome_extensions_api_client.cc b/chromium/chrome/browser/extensions/api/chrome_extensions_api_client.cc index 4772d8e3c12..10b8986f9d6 100644 --- a/chromium/chrome/browser/extensions/api/chrome_extensions_api_client.cc +++ b/chromium/chrome/browser/extensions/api/chrome_extensions_api_client.cc @@ -39,8 +39,6 @@ #include "chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.h" #include "chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.h" #include "chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.h" -#include "chrome/browser/performance_manager/performance_manager.h" -#include "chrome/browser/performance_manager/performance_manager_tab_helper.h" #include "chrome/browser/search/instant_service.h" #include "chrome/browser/search/instant_service_factory.h" #include "chrome/browser/ui/pdf/chrome_pdf_web_contents_helper_client.h" @@ -48,6 +46,8 @@ #include "chrome/common/url_constants.h" #include "chrome/common/webui_url_constants.h" #include "components/pdf/browser/pdf_web_contents_helper.h" +#include "components/performance_manager/performance_manager_tab_helper.h" +#include "components/performance_manager/public/performance_manager.h" #include "components/signin/core/browser/signin_header_helper.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" diff --git a/chromium/chrome/browser/extensions/api/commands/command_service.cc b/chromium/chrome/browser/extensions/api/commands/command_service.cc index 6f1e04fcaf5..67601761cf7 100644 --- a/chromium/chrome/browser/extensions/api/commands/command_service.cc +++ b/chromium/chrome/browser/extensions/api/commands/command_service.cc @@ -27,7 +27,6 @@ #include "content/public/browser/notification_service.h" #include "extensions/browser/extension_function_registry.h" #include "extensions/browser/extension_prefs.h" -#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/notification_types.h" #include "extensions/common/feature_switch.h" @@ -109,8 +108,7 @@ void CommandService::RegisterProfilePrefs( } CommandService::CommandService(content::BrowserContext* context) - : profile_(Profile::FromBrowserContext(context)), - extension_registry_observer_(this) { + : profile_(Profile::FromBrowserContext(context)) { ExtensionFunctionRegistry::GetInstance() .RegisterFunction<GetAllCommandsFunction>(); @@ -554,7 +552,6 @@ bool CommandService::CanAutoAssign(const Command &command, return true; if (command.global()) { - using namespace extensions; if (command.command_name() == manifest_values::kBrowserActionCommandEvent || command.command_name() == manifest_values::kPageActionCommandEvent) return false; // Browser and page actions are not global in nature. diff --git a/chromium/chrome/browser/extensions/api/commands/command_service.h b/chromium/chrome/browser/extensions/api/commands/command_service.h index 6f3e1e89a9c..73251ed8ebc 100644 --- a/chromium/chrome/browser/extensions/api/commands/command_service.h +++ b/chromium/chrome/browser/extensions/api/commands/command_service.h @@ -12,6 +12,7 @@ #include "base/scoped_observer.h" #include "chrome/common/extensions/command.h" #include "extensions/browser/browser_context_keyed_api_factory.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry_observer.h" #include "extensions/common/extension.h" @@ -30,7 +31,6 @@ class PrefRegistrySyncable; } namespace extensions { -class ExtensionRegistry; // This service keeps track of preferences related to extension commands // (assigning initial keybindings on install and removing them on deletion @@ -263,7 +263,7 @@ class CommandService : public BrowserContextKeyedAPI, Profile* profile_; ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - extension_registry_observer_; + extension_registry_observer_{this}; base::ObserverList<Observer>::Unchecked observers_; diff --git a/chromium/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc b/chromium/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc index ede8794e010..a2fabc3ef4e 100644 --- a/chromium/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc +++ b/chromium/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc @@ -400,17 +400,38 @@ IN_PROC_BROWSER_TEST_F(ExtensionContentSettingsApiTest, "ContentSettings.ExtensionNonEmbeddedSettingSet", 2); } -IN_PROC_BROWSER_TEST_F(ExtensionContentSettingsApiTest, EmbeddedSettings) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndDisableFeature(features::kPermissionDelegation); +class ExtensionContentSettingsApiTestWithPermissionDelegationDisabled + : public ExtensionContentSettingsApiTest { + public: + ExtensionContentSettingsApiTestWithPermissionDelegationDisabled() { + feature_list_.InitAndDisableFeature(features::kPermissionDelegation); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +class ExtensionContentSettingsApiTestWithPermissionDelegationEnabled + : public ExtensionContentSettingsApiTest { + public: + ExtensionContentSettingsApiTestWithPermissionDelegationEnabled() { + feature_list_.InitAndEnableFeature(features::kPermissionDelegation); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +IN_PROC_BROWSER_TEST_F( + ExtensionContentSettingsApiTestWithPermissionDelegationDisabled, + EmbeddedSettings) { const char kExtensionPath[] = "content_settings/embeddedsettings"; EXPECT_TRUE(RunExtensionSubtest(kExtensionPath, "test.html")) << message_; } -IN_PROC_BROWSER_TEST_F(ExtensionContentSettingsApiTest, - EmbeddedSettingsPermissionDelegation) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kPermissionDelegation); +IN_PROC_BROWSER_TEST_F( + ExtensionContentSettingsApiTestWithPermissionDelegationEnabled, + EmbeddedSettings) { const char kExtensionPath[] = "content_settings/embeddedsettings"; EXPECT_TRUE( RunExtensionSubtest(kExtensionPath, "test.html?permission_delegation")) diff --git a/chromium/chrome/browser/extensions/api/content_settings/content_settings_service.cc b/chromium/chrome/browser/extensions/api/content_settings/content_settings_service.cc index 47757999355..5ef415d0622 100644 --- a/chromium/chrome/browser/extensions/api/content_settings/content_settings_service.cc +++ b/chromium/chrome/browser/extensions/api/content_settings/content_settings_service.cc @@ -6,15 +6,13 @@ #include "base/lazy_instance.h" #include "base/memory/scoped_refptr.h" -#include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_prefs_scope.h" #include "extensions/browser/pref_names.h" namespace extensions { ContentSettingsService::ContentSettingsService(content::BrowserContext* context) - : content_settings_store_(base::MakeRefCounted<ContentSettingsStore>()), - scoped_observer_(this) {} + : content_settings_store_(base::MakeRefCounted<ContentSettingsStore>()) {} ContentSettingsService::~ContentSettingsService() {} diff --git a/chromium/chrome/browser/extensions/api/content_settings/content_settings_service.h b/chromium/chrome/browser/extensions/api/content_settings/content_settings_service.h index 4887f5ee2cd..c5a86f87f42 100644 --- a/chromium/chrome/browser/extensions/api/content_settings/content_settings_service.h +++ b/chromium/chrome/browser/extensions/api/content_settings/content_settings_service.h @@ -10,12 +10,12 @@ #include "base/scoped_observer.h" #include "chrome/browser/extensions/api/content_settings/content_settings_store.h" #include "extensions/browser/browser_context_keyed_api_factory.h" +#include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_prefs_observer.h" namespace extensions { class ContentSettingsStore; -class ExtensionPrefs; // This service hosts a single ContentSettingsStore for the // chrome.contentSettings API. @@ -59,7 +59,7 @@ class ContentSettingsService : public BrowserContextKeyedAPI, static const char* service_name() { return "ContentSettingsService"; } scoped_refptr<ContentSettingsStore> content_settings_store_; - ScopedObserver<ExtensionPrefs, ExtensionPrefsObserver> scoped_observer_; + ScopedObserver<ExtensionPrefs, ExtensionPrefsObserver> scoped_observer_{this}; DISALLOW_COPY_AND_ASSIGN(ContentSettingsService); }; diff --git a/chromium/chrome/browser/extensions/api/context_menus/context_menu_apitest.cc b/chromium/chrome/browser/extensions/api/context_menus/context_menu_apitest.cc index 856b74eb55e..64694816f81 100644 --- a/chromium/chrome/browser/extensions/api/context_menus/context_menu_apitest.cc +++ b/chromium/chrome/browser/extensions/api/context_menus/context_menu_apitest.cc @@ -15,9 +15,11 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/extensions/api/context_menus.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/version_info/channel.h" #include "content/public/browser/render_frame_host.h" #include "content/public/common/context_menu_params.h" #include "content/public/test/browser_test_utils.h" +#include "extensions/common/features/feature_channel.h" #include "extensions/test/result_catcher.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "ui/base/models/menu_model.h" @@ -131,6 +133,14 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContextMenus) { ASSERT_TRUE(RunExtensionTest("context_menus/event_page")) << message_; } +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ServiceWorkerContextMenus) { + // Service Workers are currently available only in Canary or trunk. + ScopedCurrentChannel current_channel_override(version_info::Channel::UNKNOWN); + ASSERT_TRUE(RunExtensionTestWithFlags("context_menus/event_page", + kFlagRunAsServiceWorkerBasedExtension)) + << message_; +} + // crbug.com/51436 -- creating context menus from multiple script contexts // should work. IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContextMenusFromMultipleContexts) { diff --git a/chromium/chrome/browser/extensions/api/context_menus/context_menus_api.cc b/chromium/chrome/browser/extensions/api/context_menus/context_menus_api.cc index 7dcb4268162..4f86af25919 100644 --- a/chromium/chrome/browser/extensions/api/context_menus/context_menus_api.cc +++ b/chromium/chrome/browser/extensions/api/context_menus/context_menus_api.cc @@ -20,8 +20,9 @@ using extensions::ErrorUtils; namespace { -const char kIdRequiredError[] = "Extensions using event pages must pass an " - "id parameter to chrome.contextMenus.create"; +const char kIdRequiredError[] = + "Extensions using event pages or Service " + "Workers must pass an id parameter to chrome.contextMenus.create"; } // namespace @@ -37,7 +38,7 @@ ExtensionFunction::ResponseAction ContextMenusCreateFunction::Run() { if (params->create_properties.id.get()) { id.string_uid = *params->create_properties.id; } else { - if (BackgroundInfo::HasLazyBackgroundPage(extension())) + if (context_menus_api_helpers::HasLazyContext(extension())) return RespondNow(Error(kIdRequiredError)); // The Generated Id is added by context_menus_custom_bindings.js. diff --git a/chromium/chrome/browser/extensions/api/context_menus/context_menus_api_helpers.cc b/chromium/chrome/browser/extensions/api/context_menus/context_menus_api_helpers.cc index f1111052bc0..a4f8124fa44 100644 --- a/chromium/chrome/browser/extensions/api/context_menus/context_menus_api_helpers.cc +++ b/chromium/chrome/browser/extensions/api/context_menus/context_menus_api_helpers.cc @@ -21,9 +21,11 @@ const char kDuplicateIDError[] = const char kGeneratedIdKey[] = "generatedId"; const char kLauncherNotAllowedError[] = "Only packaged apps are allowed to use 'launcher' context"; -const char kOnclickDisallowedError[] = "Extensions using event pages cannot " - "pass an onclick parameter to chrome.contextMenus.create. Instead, use " - "the chrome.contextMenus.onClicked event."; +const char kOnclickDisallowedError[] = + "Extensions using event pages or " + "Service Workers cannot pass an onclick parameter to " + "chrome.contextMenus.create. Instead, use the " + "chrome.contextMenus.onClicked event."; const char kParentsMustBeNormalError[] = "Parent items must have type \"normal\""; const char kTitleNeededError[] = @@ -121,5 +123,10 @@ MenuItem::Type GetType(extensions::api::context_menus::ItemType type, return extensions::MenuItem::NORMAL; } +bool HasLazyContext(const Extension* extension) { + return BackgroundInfo::HasLazyBackgroundPage(extension) || + BackgroundInfo::IsServiceWorkerBased(extension); +} + } // namespace context_menus_api_helpers } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/context_menus/context_menus_api_helpers.h b/chromium/chrome/browser/extensions/api/context_menus/context_menus_api_helpers.h index 7dc82e0fd1a..28335e39113 100644 --- a/chromium/chrome/browser/extensions/api/context_menus/context_menus_api_helpers.h +++ b/chromium/chrome/browser/extensions/api/context_menus/context_menus_api_helpers.h @@ -61,6 +61,8 @@ MenuItem::ContextList GetContexts(const std::vector< MenuItem::Type GetType(extensions::api::context_menus::ItemType type, MenuItem::Type default_type); +bool HasLazyContext(const Extension* extension); + // Creates and adds a menu item from |create_properties|. template <typename PropertyWithEnumT> bool CreateMenuItem(const PropertyWithEnumT& create_properties, @@ -77,7 +79,7 @@ bool CreateMenuItem(const PropertyWithEnumT& create_properties, return false; } - if (!is_webview && BackgroundInfo::HasLazyBackgroundPage(extension) && + if (!is_webview && HasLazyContext(extension) && create_properties.onclick.get()) { *error = kOnclickDisallowedError; return false; diff --git a/chromium/chrome/browser/extensions/api/cookies/cookies_api.cc b/chromium/chrome/browser/extensions/api/cookies/cookies_api.cc index aca854a958e..e30f454b5b3 100644 --- a/chromium/chrome/browser/extensions/api/cookies/cookies_api.cc +++ b/chromium/chrome/browser/extensions/api/cookies/cookies_api.cc @@ -95,9 +95,8 @@ CookiesEventRouter::CookieChangeListener::CookieChangeListener( CookiesEventRouter::CookieChangeListener::~CookieChangeListener() = default; void CookiesEventRouter::CookieChangeListener::OnCookieChange( - const net::CanonicalCookie& canonical_cookie, - network::mojom::CookieChangeCause cause) { - router_->OnCookieChange(otr_, canonical_cookie, cause); + const net::CookieChangeInfo& change) { + router_->OnCookieChange(otr_, change); } CookiesEventRouter::CookiesEventRouter(content::BrowserContext* context) @@ -110,50 +109,48 @@ CookiesEventRouter::~CookiesEventRouter() { BrowserList::RemoveObserver(this); } -void CookiesEventRouter::OnCookieChange( - bool otr, - const net::CanonicalCookie& canonical_cookie, - network::mojom::CookieChangeCause cause) { +void CookiesEventRouter::OnCookieChange(bool otr, + const net::CookieChangeInfo& change) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); std::unique_ptr<base::ListValue> args(new base::ListValue()); std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); dict->SetBoolean(cookies_api_constants::kRemovedKey, - cause != network::mojom::CookieChangeCause::INSERTED); + change.cause != net::CookieChangeCause::INSERTED); Profile* profile = otr ? profile_->GetOffTheRecordProfile() : profile_->GetOriginalProfile(); api::cookies::Cookie cookie = cookies_helpers::CreateCookie( - canonical_cookie, cookies_helpers::GetStoreIdFromProfile(profile)); + change.cookie, cookies_helpers::GetStoreIdFromProfile(profile)); dict->Set(cookies_api_constants::kCookieKey, cookie.ToValue()); // Map the internal cause to an external string. std::string cause_dict_entry; - switch (cause) { + switch (change.cause) { // Report an inserted cookie as an "explicit" change cause. All other causes // only make sense for deletions. - case network::mojom::CookieChangeCause::INSERTED: - case network::mojom::CookieChangeCause::EXPLICIT: + case net::CookieChangeCause::INSERTED: + case net::CookieChangeCause::EXPLICIT: cause_dict_entry = cookies_api_constants::kExplicitChangeCause; break; - case network::mojom::CookieChangeCause::OVERWRITE: + case net::CookieChangeCause::OVERWRITE: cause_dict_entry = cookies_api_constants::kOverwriteChangeCause; break; - case network::mojom::CookieChangeCause::EXPIRED: + case net::CookieChangeCause::EXPIRED: cause_dict_entry = cookies_api_constants::kExpiredChangeCause; break; - case network::mojom::CookieChangeCause::EVICTED: + case net::CookieChangeCause::EVICTED: cause_dict_entry = cookies_api_constants::kEvictedChangeCause; break; - case network::mojom::CookieChangeCause::EXPIRED_OVERWRITE: + case net::CookieChangeCause::EXPIRED_OVERWRITE: cause_dict_entry = cookies_api_constants::kExpiredOverwriteChangeCause; break; - case network::mojom::CookieChangeCause::UNKNOWN_DELETION: + case net::CookieChangeCause::UNKNOWN_DELETION: NOTREACHED(); } dict->SetString(cookies_api_constants::kCauseKey, cause_dict_entry); @@ -162,7 +159,7 @@ void CookiesEventRouter::OnCookieChange( DispatchEvent(profile, events::COOKIES_ON_CHANGED, api::cookies::OnChanged::kEventName, std::move(args), - cookies_helpers::GetURLFromCanonicalCookie(canonical_cookie)); + cookies_helpers::GetURLFromCanonicalCookie(change.cookie)); } void CookiesEventRouter::OnBrowserAdded(Browser* browser) { diff --git a/chromium/chrome/browser/extensions/api/cookies/cookies_api.h b/chromium/chrome/browser/extensions/api/cookies/cookies_api.h index ac95fc35736..0761d5333fb 100644 --- a/chromium/chrome/browser/extensions/api/cookies/cookies_api.h +++ b/chromium/chrome/browser/extensions/api/cookies/cookies_api.h @@ -22,6 +22,7 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "net/cookies/canonical_cookie.h" +#include "net/cookies/cookie_change_dispatcher.h" #include "services/network/public/mojom/cookie_manager.mojom.h" #include "url/gurl.h" @@ -49,8 +50,7 @@ class CookiesEventRouter : public BrowserListObserver { ~CookieChangeListener() override; // network::mojom::CookieChangeListener: - void OnCookieChange(const net::CanonicalCookie& canonical_cookie, - network::mojom::CookieChangeCause cause) override; + void OnCookieChange(const net::CookieChangeInfo& change) override; private: CookiesEventRouter* router_; @@ -65,9 +65,7 @@ class CookiesEventRouter : public BrowserListObserver { Profile* profile); void OnConnectionError( mojo::Receiver<network::mojom::CookieChangeListener>* receiver); - void OnCookieChange(bool otr, - const net::CanonicalCookie& canonical_cookie, - network::mojom::CookieChangeCause cause); + void OnCookieChange(bool otr, const net::CookieChangeInfo& change); // This method dispatches events to the extension message service. void DispatchEvent(content::BrowserContext* context, diff --git a/chromium/chrome/browser/extensions/api/cookies/cookies_helpers.cc b/chromium/chrome/browser/extensions/api/cookies/cookies_helpers.cc index f4dfc24b93c..386592c8654 100644 --- a/chromium/chrome/browser/extensions/api/cookies/cookies_helpers.cc +++ b/chromium/chrome/browser/extensions/api/cookies/cookies_helpers.cc @@ -103,7 +103,6 @@ Cookie CreateCookie(const net::CanonicalCookie& canonical_cookie, cookie.secure = canonical_cookie.IsSecure(); cookie.http_only = canonical_cookie.IsHttpOnly(); - DCHECK(net::IsValidSameSiteValue(canonical_cookie.SameSite())); switch (canonical_cookie.SameSite()) { case net::CookieSameSite::NO_RESTRICTION: cookie.same_site = api::cookies::SAME_SITE_STATUS_NO_RESTRICTION; @@ -118,8 +117,6 @@ Cookie CreateCookie(const net::CanonicalCookie& canonical_cookie, case net::CookieSameSite::UNSPECIFIED: cookie.same_site = api::cookies::SAME_SITE_STATUS_UNSPECIFIED; break; - default: - NOTREACHED(); } cookie.session = !canonical_cookie.IsPersistent(); diff --git a/chromium/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc b/chromium/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc index da020fe3416..0a4dc66eb5e 100644 --- a/chromium/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc +++ b/chromium/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc @@ -25,6 +25,10 @@ #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "url/origin.h" +#if defined(OS_WIN) +#include "device/fido/win/webauthn_api.h" +#endif // defined(OS_WIN) + namespace { // U2FAttestationPromptResult enumerates events related to attestation prompts. @@ -209,6 +213,23 @@ CryptotokenPrivateCanAppIdGetAttestationFunction::Run() { return RespondNow(OneArgument(std::make_unique<base::Value>(true))); } +#if defined(OS_WIN) + // If the request was handled by the Windows WebAuthn API on a version of + // Windows that shows an attestation permission prompt, don't show another + // one. + // + // Note that this does not account for the possibility of the + // WinWebAuthnApi having been disabled by a FidoDiscoveryFactory override, + // which may be done in tests or via the Virtual Authenticator WebDriver + // API. + if (base::FeatureList::IsEnabled(device::kWebAuthUseNativeWinApi) && + device::WinWebAuthnApi::GetDefault()->IsAvailable() && + device::WinWebAuthnApi::GetDefault()->Version() >= + WEBAUTHN_API_VERSION_2) { + return RespondNow(OneArgument(std::make_unique<base::Value>(true))); + } +#endif // defined(OS_WIN) + // Otherwise, show a permission prompt and pass the user's decision back. const GURL app_id_url(app_id); EXTENSION_FUNCTION_VALIDATE(app_id_url.is_valid()); diff --git a/chromium/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc b/chromium/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc index 4ed224a3259..092a999f02e 100644 --- a/chromium/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc +++ b/chromium/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc @@ -23,14 +23,10 @@ #include "extensions/browser/extension_function_dispatcher.h" #include "testing/gtest/include/gtest/gtest.h" -using crypto::SHA256HashString; - namespace extensions { namespace { -using namespace api::cryptotoken_private; - bool GetSingleBooleanResult(ExtensionFunction* function, bool* result) { const base::ListValue* result_list = function->GetResultList(); if (!result_list) { @@ -83,8 +79,8 @@ class CryptoTokenPrivateApiTest : public extensions::ExtensionApiUnittest { function->set_has_callback(true); auto args = std::make_unique<base::Value>(base::Value::Type::LIST); - args->GetList().emplace_back( - base::Value::BlobStorage(app_id.begin(), app_id.end())); + args->Append( + base::Value(base::Value::BlobStorage(app_id.begin(), app_id.end()))); if (!extension_function_test_utils::RunFunction( function.get(), base::ListValue::From(std::move(args)), browser(), @@ -133,9 +129,9 @@ TEST_F(CryptoTokenPrivateApiTest, CanOriginAssertAppId) { TEST_F(CryptoTokenPrivateApiTest, IsAppIdHashInEnterpriseContext) { const std::string example_com("https://example.com/"); - const std::string example_com_hash(SHA256HashString(example_com)); - const std::string rp_id_hash(SHA256HashString("example.com")); - const std::string foo_com_hash(SHA256HashString("https://foo.com/")); + const std::string example_com_hash(crypto::SHA256HashString(example_com)); + const std::string rp_id_hash(crypto::SHA256HashString("example.com")); + const std::string foo_com_hash(crypto::SHA256HashString("https://foo.com/")); bool result; ASSERT_TRUE(GetAppIdHashInEnterpriseContext(example_com_hash, &result)); @@ -210,7 +206,7 @@ class CryptoTokenPermissionTest : public ExtensionApiUnittest { dict.emplace("tabId", std::make_unique<base::Value>(tab_id_)); dict.emplace("origin", std::make_unique<base::Value>(app_id)); auto args = std::make_unique<base::Value>(base::Value::Type::LIST); - args->GetList().emplace_back(std::move(dict)); + args->Append(base::Value(std::move(dict))); auto args_list = base::ListValue::From(std::move(args)); extension_function_test_utils::RunFunction( diff --git a/chromium/chrome/browser/extensions/api/debugger/debugger_api.cc b/chromium/chrome/browser/extensions/api/debugger/debugger_api.cc index 6c79f07702a..9e2cb329d88 100644 --- a/chromium/chrome/browser/extensions/api/debugger/debugger_api.cc +++ b/chromium/chrome/browser/extensions/api/debugger/debugger_api.cc @@ -180,7 +180,7 @@ class ExtensionDevToolsClientHost : public content::DevToolsAgentHostClient, // Listen to extension unloaded notification. ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - extension_registry_observer_; + extension_registry_observer_{this}; DISALLOW_COPY_AND_ASSIGN(ExtensionDevToolsClientHost); }; @@ -195,8 +195,7 @@ ExtensionDevToolsClientHost::ExtensionDevToolsClientHost( extension_(std::move(extension)), last_request_id_(0), infobar_(nullptr), - detach_reason_(api::debugger::DETACH_REASON_TARGET_CLOSED), - extension_registry_observer_(this) { + detach_reason_(api::debugger::DETACH_REASON_TARGET_CLOSED) { CopyDebuggee(&debuggee_, debuggee); g_attached_client_hosts.Get().insert(this); diff --git a/chromium/chrome/browser/extensions/api/declarative/rules_registry_with_cache_unittest.cc b/chromium/chrome/browser/extensions/api/declarative/rules_registry_with_cache_unittest.cc index 6d91223e12d..997fed5c4e1 100644 --- a/chromium/chrome/browser/extensions/api/declarative/rules_registry_with_cache_unittest.cc +++ b/chromium/chrome/browser/extensions/api/declarative/rules_registry_with_cache_unittest.cc @@ -255,7 +255,7 @@ TEST_F(RulesRegistryWithCacheTest, DeclarativeRulesStored) { // 2. Test writing behavior. { base::Value value(base::Value::Type::LIST); - value.GetList().push_back(base::Value(true)); + value.Append(base::Value(true)); cache_delegate->UpdateRules(extension1_->id(), std::move(value)); } EXPECT_TRUE(cache_delegate->GetDeclarativeRulesStored(extension1_->id())); @@ -302,7 +302,7 @@ TEST_F(RulesRegistryWithCacheTest, EphemeralCacheIsEphemeral) { auto cache_delegate = std::make_unique<RulesCacheDelegate>( RulesCacheDelegate::Type::kEphemeral, false); base::Value value(base::Value::Type::LIST); - value.GetList().push_back(base::Value(true)); + value.Append(base::Value(true)); cache_delegate->UpdateRules(extension1_->id(), std::move(value)); content::RunAllTasksUntilIdle(); TestingValueStore* store = env_.GetExtensionSystem()->value_store(); diff --git a/chromium/chrome/browser/extensions/api/declarative_content/declarative_content_apitest.cc b/chromium/chrome/browser/extensions/api/declarative_content/declarative_content_apitest.cc index c75ebb8b91f..778095d72b1 100644 --- a/chromium/chrome/browser/extensions/api/declarative_content/declarative_content_apitest.cc +++ b/chromium/chrome/browser/extensions/api/declarative_content/declarative_content_apitest.cc @@ -967,16 +967,10 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, } // https://crbug.com/517492 -#if defined(OS_WIN) // Fails on XP: http://crbug.com/515717 -#define MAYBE_RemoveAllRulesAfterExtensionUninstall \ - DISABLED_RemoveAllRulesAfterExtensionUninstall -#else -#define MAYBE_RemoveAllRulesAfterExtensionUninstall \ - RemoveAllRulesAfterExtensionUninstall -#endif +// Fails on other platfomrs: http://crbug.com/1013457 IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, - MAYBE_RemoveAllRulesAfterExtensionUninstall) { + DISABLED_RemoveAllRulesAfterExtensionUninstall) { ext_dir_.WriteManifest(kDeclarativeContentManifest); ext_dir_.WriteFile(FILE_PATH_LITERAL("background.js"), kBackgroundHelpers); @@ -1015,7 +1009,6 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, ExecuteScriptInBackgroundPage(extension->id(), kRemoveTestRule1)); } - // TODO(wittman): Once ChromeContentRulesRegistry operates on condition and // action interfaces, add a test that checks that a navigation always evaluates // consistent URL state for all conditions. i.e.: if condition1 evaluates to diff --git a/chromium/chrome/browser/extensions/api/declarative_content/declarative_content_is_bookmarked_condition_tracker.cc b/chromium/chrome/browser/extensions/api/declarative_content/declarative_content_is_bookmarked_condition_tracker.cc index 5d8e60d10c6..a63a5d95fc3 100644 --- a/chromium/chrome/browser/extensions/api/declarative_content/declarative_content_is_bookmarked_condition_tracker.cc +++ b/chromium/chrome/browser/extensions/api/declarative_content/declarative_content_is_bookmarked_condition_tracker.cc @@ -10,7 +10,6 @@ #include "base/strings/stringprintf.h" #include "base/values.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" -#include "components/bookmarks/browser/bookmark_model.h" #include "content/public/browser/web_contents.h" #include "extensions/common/api/declarative/declarative_constants.h" #include "extensions/common/permissions/permissions_data.h" @@ -147,11 +146,10 @@ WebContentsDestroyed() { // DeclarativeContentIsBookmarkedConditionTracker:: -DeclarativeContentIsBookmarkedConditionTracker(content::BrowserContext* context, - Delegate* delegate) - : delegate_(delegate), - extensive_bookmark_changes_in_progress_(0), - scoped_bookmarks_observer_(this) { + DeclarativeContentIsBookmarkedConditionTracker( + content::BrowserContext* context, + Delegate* delegate) + : delegate_(delegate), extensive_bookmark_changes_in_progress_(0) { bookmarks::BookmarkModel* bookmark_model = BookmarkModelFactory::GetForBrowserContext(context); // Can be null during unit test execution. diff --git a/chromium/chrome/browser/extensions/api/declarative_content/declarative_content_is_bookmarked_condition_tracker.h b/chromium/chrome/browser/extensions/api/declarative_content/declarative_content_is_bookmarked_condition_tracker.h index 7cbc0b2fa56..76b38a7ad9d 100644 --- a/chromium/chrome/browser/extensions/api/declarative_content/declarative_content_is_bookmarked_condition_tracker.h +++ b/chromium/chrome/browser/extensions/api/declarative_content/declarative_content_is_bookmarked_condition_tracker.h @@ -14,6 +14,7 @@ #include "base/scoped_observer.h" #include "chrome/browser/extensions/api/declarative_content/content_predicate_evaluator.h" #include "components/bookmarks/browser/base_bookmark_model_observer.h" +#include "components/bookmarks/browser/bookmark_model.h" #include "content/public/browser/web_contents_observer.h" #include "extensions/common/extension.h" @@ -158,7 +159,7 @@ class DeclarativeContentIsBookmarkedConditionTracker int extensive_bookmark_changes_in_progress_; ScopedObserver<bookmarks::BookmarkModel, bookmarks::BookmarkModelObserver> - scoped_bookmarks_observer_; + scoped_bookmarks_observer_{this}; DISALLOW_COPY_AND_ASSIGN(DeclarativeContentIsBookmarkedConditionTracker); }; diff --git a/chromium/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc b/chromium/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc index e704227958c..7ebbb0567b3 100644 --- a/chromium/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc +++ b/chromium/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc @@ -2798,6 +2798,110 @@ IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, EXPECT_EQ(first_tab_badge_text, action->GetDisplayBadgeText(first_tab_id)); } +// Ensure web request events are still dispatched even if DNR blocks/redirects +// the request. (Regression test for crbug.com/999744). +IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, WebRequestEvents) { + // Load the extension with a background script so scripts can be run from its + // generated background page. + set_has_background_script(true); + + TestRule rule = CreateGenericRule(); + rule.condition->url_filter = "||example.com"; + rule.condition->resource_types = std::vector<std::string>({"main_frame"}); + ASSERT_NO_FATAL_FAILURE(LoadExtensionWithRules( + {rule}, "test_extension", {URLPattern::kAllUrlsPattern})); + + GURL url = embedded_test_server()->GetURL("example.com", + "/pages_with_script/index.html"); + + // Set up web request listeners listening to request to |url|. + const char kWebRequestListenerScript[] = R"( + let filter = {'urls' : ['%s'], 'types' : ['main_frame']}; + + let onBeforeRequestSeen = false; + chrome.webRequest.onBeforeRequest.addListener(() => { + onBeforeRequestSeen = true; + }, filter); + + // The request will fail since it will be blocked by DNR. + chrome.webRequest.onErrorOccurred.addListener(() => { + if (onBeforeRequestSeen) + chrome.test.sendMessage('PASS'); + }, filter); + + chrome.test.sendMessage('INSTALLED'); + )"; + + ExtensionTestMessageListener pass_listener("PASS", false /* will_reply */); + ExtensionTestMessageListener installed_listener("INSTALLED", + false /* will_reply */); + ExecuteScriptInBackgroundPageNoWait( + last_loaded_extension_id(), + base::StringPrintf(kWebRequestListenerScript, url.spec().c_str())); + + // Wait for the web request listeners to be installed before navigating. + ASSERT_TRUE(installed_listener.WaitUntilSatisfied()); + + ui_test_utils::NavigateToURL(browser(), url); + + ASSERT_FALSE(WasFrameWithScriptLoaded(GetMainFrame())); + EXPECT_TRUE(pass_listener.WaitUntilSatisfied()); +} + +// Ensure Declarative Net Request gets priority over the web request API. +IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, WebRequestPriority) { + // Load the extension with a background script so scripts can be run from its + // generated background page. + set_has_background_script(true); + + GURL url = embedded_test_server()->GetURL("example.com", + "/pages_with_script/index.html"); + GURL redirect_url = embedded_test_server()->GetURL( + "redirect.com", "/pages_with_script/index.html"); + + TestRule example_com_redirect_rule = CreateGenericRule(); + example_com_redirect_rule.condition->url_filter = "||example.com"; + example_com_redirect_rule.condition->resource_types = + std::vector<std::string>({"main_frame"}); + example_com_redirect_rule.action->type = std::string("redirect"); + example_com_redirect_rule.action->redirect.emplace(); + example_com_redirect_rule.action->redirect->url = redirect_url.spec(); + example_com_redirect_rule.priority = kMinValidPriority; + + ASSERT_NO_FATAL_FAILURE( + LoadExtensionWithRules({example_com_redirect_rule}, "test_extension", + {URLPattern::kAllUrlsPattern})); + + // Set up a web request listener to block the request to example.com. + const char kWebRequestBlockScript[] = R"( + let filter = {'urls' : ['%s'], 'types' : ['main_frame']}; + chrome.webRequest.onBeforeRequest.addListener((details) => { + chrome.test.sendMessage('SEEN') + }, filter, ['blocking']); + chrome.test.sendMessage('INSTALLED'); + )"; + + ExtensionTestMessageListener seen_listener("SEEN", false /* will_reply */); + ExtensionTestMessageListener installed_listener("INSTALLED", + false /* will_reply */); + ExecuteScriptInBackgroundPageNoWait( + last_loaded_extension_id(), + base::StringPrintf(kWebRequestBlockScript, url.spec().c_str())); + + // Wait for the web request listeners to be installed before navigating. + ASSERT_TRUE(installed_listener.WaitUntilSatisfied()); + + ui_test_utils::NavigateToURL(browser(), url); + + // Ensure the response from the web request listener was ignored and the + // request was redirected. + ASSERT_TRUE(WasFrameWithScriptLoaded(GetMainFrame())); + EXPECT_EQ(web_contents()->GetLastCommittedURL(), redirect_url); + + // Ensure onBeforeRequest is seen by the web request extension. + EXPECT_TRUE(seen_listener.WaitUntilSatisfied()); +} + // Test that the extension cannot retrieve the number of actions matched // from the badge text by calling chrome.browserAction.getBadgeText. IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, @@ -3046,6 +3150,116 @@ IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, } } +// Test that the badge text for extensions will update correctly for +// removeHeader rules. +IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, + RemoveHeadersBadgeText) { + auto referer_url = embedded_test_server()->GetURL( + "example.com", "/set-header?referer: none"); + auto set_cookie_url = + embedded_test_server()->GetURL("example.com", "/set-cookie?a=b"); + + // Navigates frame with name |frame_name| to |url|. + auto navigate_frame = [this](const std::string& frame_name, const GURL& url, + bool use_frame_referrer) { + content::TestNavigationObserver navigation_observer( + web_contents(), 1 /*number_of_navigations*/); + + const char* referrer_policy = use_frame_referrer ? "origin" : "no-referrer"; + + ASSERT_TRUE(content::ExecuteScript( + GetMainFrame(), + base::StringPrintf(R"( + document.getElementsByName('%s')[0].referrerPolicy = '%s'; + document.getElementsByName('%s')[0].src = '%s';)", + frame_name.c_str(), referrer_policy, + frame_name.c_str(), url.spec().c_str()))); + navigation_observer.Wait(); + }; + + const std::string kFrameName1 = "frame1"; + const GURL page_url = embedded_test_server()->GetURL( + "nomatch.com", "/page_with_two_frames.html"); + + // Create an extension with a rule to remove the Set-Cookie header, and get + // the ExtensionAction for it. + TestRule rule1 = CreateGenericRule(); + rule1.id = kMinValidID; + rule1.condition->url_filter = "example.com"; + rule1.condition->resource_types = std::vector<std::string>({"sub_frame"}); + rule1.action->type = "removeHeaders"; + rule1.action->remove_headers_list = std::vector<std::string>({"setCookie"}); + + ASSERT_NO_FATAL_FAILURE(LoadExtensionWithRules({rule1}, "extension_1", {})); + + const ExtensionId remove_set_cookie_ext_id = last_loaded_extension_id(); + ExtensionPrefs::Get(profile())->SetDNRUseActionCountAsBadgeText( + remove_set_cookie_ext_id, true); + + ExtensionAction* remove_set_cookie_action = + ExtensionActionManager::Get(web_contents()->GetBrowserContext()) + ->GetExtensionAction(*extension_registry()->GetExtensionById( + remove_set_cookie_ext_id, + extensions::ExtensionRegistry::ENABLED)); + + // Create an extension with a rule to remove the referer header, and get the + // ExtensionAction for it. + TestRule rule2 = CreateGenericRule(); + rule2.id = kMinValidID; + rule2.condition->url_filter = "example.com"; + rule2.condition->resource_types = std::vector<std::string>({"sub_frame"}); + rule2.action->type = "removeHeaders"; + rule2.action->remove_headers_list = std::vector<std::string>({"referer"}); + + ASSERT_NO_FATAL_FAILURE(LoadExtensionWithRules({rule2}, "extension_2", {})); + + const ExtensionId remove_referer_ext_id = last_loaded_extension_id(); + ExtensionPrefs::Get(profile())->SetDNRUseActionCountAsBadgeText( + remove_referer_ext_id, true); + + ExtensionAction* remove_referer_action = + ExtensionActionManager::Get(web_contents()->GetBrowserContext()) + ->GetExtensionAction(*extension_registry()->GetExtensionById( + remove_referer_ext_id, extensions::ExtensionRegistry::ENABLED)); + + struct { + GURL url; + bool use_referrer; + std::string expected_remove_referer_badge_text; + std::string expected_remove_set_cookie_badge_text; + } test_cases[] = { + // This request only has a Set-Cookie header. Only the badge text for the + // extension with a remove Set-Cookie header rule should be incremented. + {set_cookie_url, false, "0", "1"}, + // This request only has a Referer header. Only the badge text for the + // extension with a remove Referer header rule should be incremented. + {referer_url, true, "1", "1"}, + // This request has both a Referer and a Set-Cookie header. The badge text + // for both extensions should be incremented. + {set_cookie_url, true, "2", "2"}, + }; + + ui_test_utils::NavigateToURL(browser(), page_url); + ASSERT_TRUE(WasFrameWithScriptLoaded(GetMainFrame())); + + int first_tab_id = ExtensionTabUtil::GetTabId(web_contents()); + EXPECT_EQ("0", remove_set_cookie_action->GetDisplayBadgeText(first_tab_id)); + EXPECT_EQ("0", remove_referer_action->GetDisplayBadgeText(first_tab_id)); + + for (const auto& test_case : test_cases) { + SCOPED_TRACE(base::StringPrintf("Testing URL: %s, using referrer: %s", + test_case.url.spec().c_str(), + test_case.use_referrer ? "true" : "false")); + + navigate_frame(kFrameName1, test_case.url, test_case.use_referrer); + EXPECT_EQ(test_case.expected_remove_set_cookie_badge_text, + remove_set_cookie_action->GetDisplayBadgeText(first_tab_id)); + + EXPECT_EQ(test_case.expected_remove_referer_badge_text, + remove_referer_action->GetDisplayBadgeText(first_tab_id)); + } +} + // Test fixture to verify that host permissions for the request url and the // request initiator are properly checked when redirecting requests. Loads an // example.com url with four sub-frames named frame_[1..4] from hosts diff --git a/chromium/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc b/chromium/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc index 808d1b52973..1251a3a2281 100644 --- a/chromium/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc +++ b/chromium/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc @@ -15,6 +15,7 @@ #include "chrome/browser/extensions/chrome_test_extension_loader.h" #include "chrome/browser/extensions/extension_util.h" #include "extensions/browser/api/declarative_net_request/composite_matcher.h" +#include "extensions/browser/api/declarative_net_request/request_action.h" #include "extensions/browser/api/declarative_net_request/ruleset_matcher.h" #include "extensions/browser/api/declarative_net_request/ruleset_source.h" #include "extensions/browser/api/declarative_net_request/test_utils.h" @@ -28,6 +29,7 @@ #include "extensions/common/file_util.h" #include "extensions/common/manifest_handlers/background_info.h" #include "extensions/common/url_pattern.h" +#include "net/http/http_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" #include "url/origin.h" @@ -37,8 +39,7 @@ namespace declarative_net_request { // Note: This is not declared in the anonymous namespace so that we can use it // with gtest. -bool operator==(const RulesetManager::Action& lhs, - const RulesetManager::Action& rhs) { +bool operator==(const RequestAction& lhs, const RequestAction& rhs) { static_assert(flat::ActionIndex_count == 7, "Modify this method to ensure it stays updated as new actions " "are added."); @@ -72,8 +73,7 @@ class RulesetManagerTest : public DNRTestBase { } protected: - using Action = RulesetManager::Action; - using ActionType = Action::Type; + using RequestActionType = RequestAction::Type; // Helper to create a composite matcher instance for the given |rules|. void CreateMatcherForRules( @@ -133,6 +133,24 @@ class RulesetManagerTest : public DNRTestBase { return info; } + // Returns renderer-initiated request params for the given |url| and + // |request_headers| request headers. + WebRequestInfoInitParams GetRequestParamsForURLWithHeaders( + base::StringPiece url, + const std::vector<std::string>& request_headers) { + const int kRendererId = 1; + WebRequestInfoInitParams info; + info.url = GURL(url); + info.render_process_id = kRendererId; + + net::HttpRequestHeaders extra_request_headers; + for (const auto& header : request_headers) + extra_request_headers.SetHeaderIfMissing(header, "foo"); + + info.extra_request_headers = extra_request_headers; + return info; + } + RulesetManager* manager() { return manager_.get(); } private: @@ -156,9 +174,10 @@ TEST_P(RulesetManagerTest, MultipleRulesets) { rule_two.condition->url_filter = std::string("two.com"); auto should_block_request = [this](const WebRequestInfo& request) { - return manager()->EvaluateRequest(request, - false /*is_incognito_context*/) == - Action(ActionType::BLOCK); + manager()->EvaluateRequest(request, false /*is_incognito_context*/); + return !request.dnr_actions->empty() && + ((*request.dnr_actions)[0] == + RequestAction(RequestActionType::BLOCK)); }; for (int mask = 0; mask < 4; mask++) { @@ -228,28 +247,34 @@ TEST_P(RulesetManagerTest, IncognitoRequests) { // incognito contexts should not be evaluated. EXPECT_FALSE(util::IsIncognitoEnabled(last_loaded_extension()->id(), browser_context())); - EXPECT_EQ( - Action(ActionType::NONE), - manager()->EvaluateRequest(request_info, true /*is_incognito_context*/)); - request_info.dnr_action.reset(); - EXPECT_EQ( - Action(ActionType::BLOCK), - manager()->EvaluateRequest(request_info, false /*is_incognito_context*/)); - request_info.dnr_action.reset(); + + manager()->EvaluateRequest(request_info, true /*is_incognito_context*/); + EXPECT_TRUE(request_info.dnr_actions->empty()); + request_info.dnr_actions.reset(); + + manager()->EvaluateRequest(request_info, false /*is_incognito_context*/); + ASSERT_EQ(1u, request_info.dnr_actions->size()); + EXPECT_EQ(RequestAction(RequestActionType::BLOCK), + (*request_info.dnr_actions)[0]); + request_info.dnr_actions.reset(); // Enabling the extension in incognito mode, should cause requests from // incognito contexts to also be evaluated. SetIncognitoEnabled(last_loaded_extension(), true /*incognito_enabled*/); EXPECT_TRUE(util::IsIncognitoEnabled(last_loaded_extension()->id(), browser_context())); - EXPECT_EQ( - Action(ActionType::BLOCK), - manager()->EvaluateRequest(request_info, true /*is_incognito_context*/)); - request_info.dnr_action.reset(); - EXPECT_EQ( - Action(ActionType::BLOCK), - manager()->EvaluateRequest(request_info, false /*is_incognito_context*/)); - request_info.dnr_action.reset(); + + manager()->EvaluateRequest(request_info, true /*is_incognito_context*/); + ASSERT_EQ(1u, request_info.dnr_actions->size()); + EXPECT_EQ(RequestAction(RequestActionType::BLOCK), + (*request_info.dnr_actions)[0]); + request_info.dnr_actions.reset(); + + manager()->EvaluateRequest(request_info, false /*is_incognito_context*/); + ASSERT_EQ(1u, request_info.dnr_actions->size()); + EXPECT_EQ(RequestAction(RequestActionType::BLOCK), + (*request_info.dnr_actions)[0]); + request_info.dnr_actions.reset(); } // Tests that @@ -265,15 +290,16 @@ TEST_P(RulesetManagerTest, TotalEvaluationTimeHistogram) { "Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions2"; { base::HistogramTester tester; - EXPECT_EQ( - Action(ActionType::NONE), - manager()->EvaluateRequest(example_com_request, is_incognito_context)); - EXPECT_EQ( - Action(ActionType::NONE), - manager()->EvaluateRequest(google_com_request, is_incognito_context)); + + manager()->EvaluateRequest(example_com_request, is_incognito_context); + EXPECT_TRUE(example_com_request.dnr_actions->empty()); + + manager()->EvaluateRequest(google_com_request, is_incognito_context); + EXPECT_TRUE(google_com_request.dnr_actions->empty()); + tester.ExpectTotalCount(kHistogramName, 0); - example_com_request.dnr_action.reset(); - google_com_request.dnr_action.reset(); + example_com_request.dnr_actions.reset(); + google_com_request.dnr_actions.reset(); } // Add an extension ruleset which blocks requests to "example.com". @@ -287,16 +313,20 @@ TEST_P(RulesetManagerTest, TotalEvaluationTimeHistogram) { { base::HistogramTester tester; - EXPECT_EQ( - Action(ActionType::BLOCK), - manager()->EvaluateRequest(example_com_request, is_incognito_context)); + + manager()->EvaluateRequest(example_com_request, is_incognito_context); + ASSERT_EQ(1u, example_com_request.dnr_actions->size()); + EXPECT_EQ(RequestAction(RequestActionType::BLOCK), + (*example_com_request.dnr_actions)[0]); + tester.ExpectTotalCount(kHistogramName, 1); - EXPECT_EQ( - Action(ActionType::NONE), - manager()->EvaluateRequest(google_com_request, is_incognito_context)); + + manager()->EvaluateRequest(google_com_request, is_incognito_context); + EXPECT_TRUE(google_com_request.dnr_actions->empty()); + tester.ExpectTotalCount(kHistogramName, 2); - example_com_request.dnr_action.reset(); - google_com_request.dnr_action.reset(); + example_com_request.dnr_actions.reset(); + google_com_request.dnr_actions.reset(); } } @@ -320,31 +350,33 @@ TEST_P(RulesetManagerTest, Redirect) { // redirected to "google.com". const bool is_incognito_context = false; const char* kExampleURL = "http://example.com"; - Action expected_redirect_action(ActionType::REDIRECT); + RequestAction expected_redirect_action(RequestActionType::REDIRECT); expected_redirect_action.redirect_url = GURL("http://google.com"); WebRequestInfo request_1(GetRequestParamsForURL(kExampleURL, base::nullopt)); - EXPECT_EQ(expected_redirect_action, - manager()->EvaluateRequest(request_1, is_incognito_context)); + manager()->EvaluateRequest(request_1, is_incognito_context); + ASSERT_EQ(1u, request_1.dnr_actions->size()); + EXPECT_EQ(expected_redirect_action, (*request_1.dnr_actions)[0]); // Change the initiator to "xyz.com". It should not be redirected since we // don't have host permissions to the request initiator. WebRequestInfo request_2(GetRequestParamsForURL( kExampleURL, url::Origin::Create(GURL("http://xyz.com")))); - EXPECT_EQ(Action(ActionType::NONE), - manager()->EvaluateRequest(request_2, is_incognito_context)); + manager()->EvaluateRequest(request_2, is_incognito_context); + EXPECT_TRUE(request_2.dnr_actions->empty()); // Change the initiator to "abc.com". It should be redirected since we have // the required host permissions. WebRequestInfo request_3(GetRequestParamsForURL( kExampleURL, url::Origin::Create(GURL("http://abc.com")))); - EXPECT_EQ(expected_redirect_action, - manager()->EvaluateRequest(request_3, is_incognito_context)); + manager()->EvaluateRequest(request_3, is_incognito_context); + ASSERT_EQ(1u, request_3.dnr_actions->size()); + EXPECT_EQ(expected_redirect_action, (*request_3.dnr_actions)[0]); // Ensure web-socket requests are not redirected. WebRequestInfo request_4( GetRequestParamsForURL("ws://example.com", base::nullopt)); - EXPECT_EQ(Action(ActionType::NONE), - manager()->EvaluateRequest(request_4, is_incognito_context)); + manager()->EvaluateRequest(request_4, is_incognito_context); + EXPECT_TRUE(request_4.dnr_actions->empty()); } // Tests that an extension can't block or redirect resources on the chrome- @@ -390,9 +422,10 @@ TEST_P(RulesetManagerTest, ExtensionScheme) { // Ensure that "http://example.com" will be blocked (with blocking taking // priority over redirection). WebRequestInfo request_1(GetRequestParamsForURL("http://example.com")); - EXPECT_EQ( - Action(ActionType::BLOCK), - manager()->EvaluateRequest(request_1, false /*is_incognito_context*/)); + manager()->EvaluateRequest(request_1, false /*is_incognito_context*/); + ASSERT_EQ(1u, request_1.dnr_actions->size()); + EXPECT_EQ(RequestAction(RequestActionType::BLOCK), + (*request_1.dnr_actions)[0]); // Ensure that the background page for |extension_1| won't be blocked or // redirected. @@ -400,9 +433,8 @@ TEST_P(RulesetManagerTest, ExtensionScheme) { EXPECT_TRUE(!background_page_url_1.is_empty()); WebRequestInfo request_2( GetRequestParamsForURL(background_page_url_1.spec())); - EXPECT_EQ( - Action(ActionType::NONE), - manager()->EvaluateRequest(request_2, false /*is_incognito_context*/)); + manager()->EvaluateRequest(request_2, false /*is_incognito_context*/); + EXPECT_TRUE(request_2.dnr_actions->empty()); // Ensure that the background page for |extension_2| won't be blocked or // redirected. @@ -410,17 +442,89 @@ TEST_P(RulesetManagerTest, ExtensionScheme) { EXPECT_TRUE(!background_page_url_2.is_empty()); WebRequestInfo request_3( GetRequestParamsForURL(background_page_url_2.spec())); - EXPECT_EQ( - Action(ActionType::NONE), - manager()->EvaluateRequest(request_3, false /*is_incognito_context*/)); + manager()->EvaluateRequest(request_3, false /*is_incognito_context*/); + EXPECT_TRUE(request_3.dnr_actions->empty()); // Also ensure that an arbitrary url on the chrome extension scheme is also // not blocked or redirected. WebRequestInfo request_4(GetRequestParamsForURL(base::StringPrintf( "%s://%s/%s", kExtensionScheme, "extension_id", "path"))); - EXPECT_EQ( - Action(ActionType::NONE), - manager()->EvaluateRequest(request_4, false /*is_incognito_context*/)); + manager()->EvaluateRequest(request_4, false /*is_incognito_context*/); + EXPECT_TRUE(request_4.dnr_actions->empty()); +} + +// Test that headers to be removed in removeHeaders rules are attributed to the +// correct extension. +TEST_P(RulesetManagerTest, RemoveHeaders) { + const Extension* extension_1 = nullptr; + const Extension* extension_2 = nullptr; + // Add an extension with a background page which removes the "cookie" and + // "setCookie" headers. + { + std::unique_ptr<CompositeMatcher> matcher; + TestRule rule = CreateGenericRule(); + rule.condition->url_filter = std::string("*"); + rule.action->type = std::string("removeHeaders"); + rule.action->remove_headers_list = + std::vector<std::string>({"cookie", "setCookie"}); + + ASSERT_NO_FATAL_FAILURE( + CreateMatcherForRules({rule}, "test extension", &matcher)); + extension_1 = last_loaded_extension(); + manager()->AddRuleset(extension_1->id(), std::move(matcher), + URLPatternSet()); + } + + // Add another extension with a background page which removes the "cookie" and + // "referer" headers. + { + std::unique_ptr<CompositeMatcher> matcher; + TestRule rule = CreateGenericRule(); + rule.condition->url_filter = std::string("*"); + rule.action->type = std::string("removeHeaders"); + rule.action->remove_headers_list = + std::vector<std::string>({"cookie", "referer"}); + + ASSERT_NO_FATAL_FAILURE( + CreateMatcherForRules({rule}, "test extension 2", &matcher)); + extension_2 = last_loaded_extension(); + manager()->AddRuleset(extension_2->id(), std::move(matcher), + URLPatternSet()); + } + + EXPECT_EQ(2u, manager()->GetMatcherCountForTest()); + + // Create a request with the "cookie" and "referer" request headers, and the + // "set-cookie" response header. + WebRequestInfo request_1(GetRequestParamsForURLWithHeaders( + "http://example.com", std::vector<std::string>({"cookie", "referer"}))); + request_1.response_headers = base::MakeRefCounted<net::HttpResponseHeaders>( + net::HttpUtil::AssembleRawHeaders("HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain; UTF-8\r\n" + "Set-Cookie: custom/value\r\n")); + + const std::vector<RequestAction>& actual_actions = + manager()->EvaluateRequest(request_1, false /*is_incognito_context*/); + ASSERT_EQ(2u, actual_actions.size()); + + // Removal of the cookie header should be attributed to |extension_2| because + // it was installed later than |extension_1| and thus has more priority. + RequestAction expected_action_1(RequestActionType::REMOVE_HEADERS); + expected_action_1.request_headers_to_remove.push_back( + net::HttpRequestHeaders::kCookie); + + // Removal of the referer header should be attributed to |extension_2|. + expected_action_1.request_headers_to_remove.push_back( + net::HttpRequestHeaders::kReferer); + + RequestAction expected_action_2(RequestActionType::REMOVE_HEADERS); + expected_action_2.response_headers_to_remove.push_back("set-cookie"); + + EXPECT_EQ(expected_action_1, actual_actions[0]); + EXPECT_EQ(extension_2->id(), actual_actions[0].extension_id); + + EXPECT_EQ(expected_action_2, actual_actions[1]); + EXPECT_EQ(extension_1->id(), actual_actions[1].extension_id); } TEST_P(RulesetManagerTest, PageAllowingAPI) { @@ -571,12 +675,16 @@ TEST_P(RulesetManagerTest, PageAllowingAPI) { frame_params.pending_main_frame_url); } - Action expected_action = test_case.expect_blocked_with_allowed_pages - ? Action(ActionType::BLOCK) - : Action(ActionType::NONE); - EXPECT_EQ(expected_action, - manager()->EvaluateRequest(WebRequestInfo(std::move(params)), - false /*is_incognito_context*/)); + WebRequestInfo request_info(std::move(params)); + const std::vector<RequestAction>& actions = manager()->EvaluateRequest( + request_info, false /*is_incognito_context*/); + + if (test_case.expect_blocked_with_allowed_pages) { + ASSERT_EQ(1u, actions.size()); + EXPECT_EQ(RequestAction(RequestActionType::BLOCK), actions[0]); + } else { + EXPECT_TRUE(actions.empty()); + } } } @@ -618,30 +726,28 @@ TEST_P(RulesetManagerTest, HostPermissionForInitiator) { struct TestCase { std::string url; base::Optional<url::Origin> initiator; - ActionType expected_action_redirect_extension; - ActionType expected_action_blocking_extension; + bool expected_action_redirect_extension; + bool expected_action_blocking_extension; } cases[] = { // Empty initiator. Has access. - {"https://example.com", base::nullopt, ActionType::REDIRECT, - ActionType::BLOCK}, + {"https://example.com", base::nullopt, true, true}, // Opaque origin as initiator. Has access. - {"https://example.com", url::Origin(), ActionType::REDIRECT, - ActionType::BLOCK}, + {"https://example.com", url::Origin(), true, true}, // yahoo.com as initiator. Has access. {"https://example.com", url::Origin::Create(GURL("http://yahoo.com")), - ActionType::REDIRECT, ActionType::BLOCK}, + true, true}, // No matching rule. {"https://yahoo.com", url::Origin::Create(GURL("http://example.com")), - ActionType::NONE, ActionType::NONE}, + false, false}, // Doesn't have access to initiator. But blocking a request doesn't // require host permissions. {"https://example.com", url::Origin::Create(GURL("http://google.com")), - ActionType::NONE, ActionType::BLOCK}, + false, true}, }; auto verify_test_case = [this](const std::string& url, const base::Optional<url::Origin>& initiator, - const Action& expected_action) { + RequestAction* expected_action) { SCOPED_TRACE(base::StringPrintf( "Url-%s initiator-%s", url.c_str(), initiator ? initiator->Serialize().c_str() : "empty")); @@ -649,8 +755,14 @@ TEST_P(RulesetManagerTest, HostPermissionForInitiator) { WebRequestInfo request(GetRequestParamsForURL(url, initiator)); bool is_incognito_context = false; - EXPECT_EQ(expected_action, - manager()->EvaluateRequest(request, is_incognito_context)); + manager()->EvaluateRequest(request, is_incognito_context); + + if (expected_action) { + ASSERT_EQ(1u, request.dnr_actions->size()); + EXPECT_EQ(*expected_action, (*request.dnr_actions)[0]); + } else { + EXPECT_TRUE(request.dnr_actions->empty()); + } }; // Test redirect extension. @@ -659,11 +771,12 @@ TEST_P(RulesetManagerTest, HostPermissionForInitiator) { manager()->AddRuleset(redirect_extension_id, std::move(redirect_matcher), URLPatternSet()); for (const auto& test : cases) { - Action expected_action(test.expected_action_redirect_extension); - if (test.expected_action_redirect_extension == ActionType::REDIRECT) - expected_action.redirect_url = GURL("https://foo.com/"); + RequestAction redirect_action(RequestActionType::REDIRECT); + redirect_action.redirect_url = GURL("https://foo.com/"); - verify_test_case(test.url, test.initiator, expected_action); + verify_test_case( + test.url, test.initiator, + test.expected_action_redirect_extension ? &redirect_action : nullptr); } manager()->RemoveRuleset(redirect_extension_id); } @@ -674,8 +787,11 @@ TEST_P(RulesetManagerTest, HostPermissionForInitiator) { manager()->AddRuleset(blocking_extension_id, std::move(blocking_matcher), URLPatternSet()); for (const auto& test : cases) { - verify_test_case(test.url, test.initiator, - Action(test.expected_action_blocking_extension)); + RequestAction block_action(RequestActionType::BLOCK); + + verify_test_case( + test.url, test.initiator, + test.expected_action_blocking_extension ? &block_action : nullptr); } manager()->RemoveRuleset(blocking_extension_id); } diff --git a/chromium/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc b/chromium/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc index 07369df425c..c0eed2de936 100644 --- a/chromium/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc +++ b/chromium/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc @@ -30,17 +30,16 @@ #include "extensions/common/manifest.h" #include "extensions/common/switches.h" #include "ui/base/l10n/l10n_util.h" +#include "url/origin.h" -using extensions::api::desktop_capture::ChooseDesktopMedia::Results::Options; using content::DesktopMediaID; +using extensions::api::desktop_capture::ChooseDesktopMedia::Results::Options; namespace extensions { namespace { const char kInvalidSourceNameError[] = "Invalid source type specified."; -const char kEmptySourcesListError[] = - "At least one source type must be specified."; DesktopMediaPickerFactory* g_picker_factory = nullptr; @@ -65,11 +64,12 @@ void DesktopCaptureChooseDesktopMediaFunctionBase::Cancel() { // Keep reference to |this| to ensure the object doesn't get destroyed before // we return. scoped_refptr<DesktopCaptureChooseDesktopMediaFunctionBase> self(this); - if (picker_) { - picker_.reset(); - SetResultList(Create(std::string(), Options())); - SendResponse(true); - } + + // If this picker dialog is open, this will close it. + picker_controller_.reset(); + + SetResultList(Create(std::string(), Options())); + SendResponse(true); } bool DesktopCaptureChooseDesktopMediaFunctionBase::Execute( @@ -77,8 +77,7 @@ bool DesktopCaptureChooseDesktopMediaFunctionBase::Execute( content::WebContents* web_contents, const GURL& origin, const base::string16 target_name) { - // Register to be notified when the tab is closed. - Observe(web_contents); + DCHECK(!picker_controller_); gfx::NativeWindow parent_window = web_contents->GetTopLevelNativeWindow(); // In case of coming from background extension page, |parent_window| will @@ -122,34 +121,20 @@ bool DesktopCaptureChooseDesktopMediaFunctionBase::Execute( } } - DesktopMediaPickerFactory* picker_factory = - g_picker_factory ? g_picker_factory - : DesktopMediaPickerFactoryImpl::GetInstance(); - // Keep same order as the input |sources| and avoid duplicates. - std::vector<std::unique_ptr<DesktopMediaList>> source_lists = - picker_factory->CreateMediaList(media_types); - if (source_lists.empty()) { - error_ = kEmptySourcesListError; - return false; - } - picker_ = picker_factory->CreatePicker(); - if (!picker_) { - error_ = "Desktop Capture API is not yet implemented for this platform."; - return false; - } - - DesktopMediaPicker::DoneCallback callback = base::Bind( + DesktopMediaPickerController::DoneCallback callback = base::BindOnce( &DesktopCaptureChooseDesktopMediaFunctionBase::OnPickerDialogResults, - this); - DesktopMediaPicker::Params picker_params; + this, origin, web_contents); + DesktopMediaPickerController::Params picker_params; picker_params.web_contents = web_contents; picker_params.context = parent_window; picker_params.parent = parent_window; picker_params.app_name = base::UTF8ToUTF16(GetCallerDisplayName()); picker_params.target_name = target_name; picker_params.request_audio = request_audio; - picker_->Show(picker_params, std::move(source_lists), callback); - origin_ = origin; + picker_controller_ = + std::make_unique<DesktopMediaPickerController>(g_picker_factory); + picker_controller_->Show(picker_params, std::move(media_types), + std::move(callback)); return true; } @@ -163,23 +148,38 @@ std::string DesktopCaptureChooseDesktopMediaFunctionBase::GetCallerDisplayName() } } -void DesktopCaptureChooseDesktopMediaFunctionBase::WebContentsDestroyed() { - Cancel(); -} - void DesktopCaptureChooseDesktopMediaFunctionBase::OnPickerDialogResults( + const GURL& origin, + content::WebContents* web_contents, + const std::string& err, DesktopMediaID source) { + picker_controller_.reset(); + + if (!err.empty()) { + SetError(err); + SendResponse(false); + return; + } + + if (source.is_null()) { + DLOG(ERROR) << "Sending empty results."; + SetResultList(Create(std::string(), Options())); + SendResponse(true); + return; + } + std::string result; - if (source.type != DesktopMediaID::TYPE_NONE && web_contents()) { + if (source.type != DesktopMediaID::TYPE_NONE && web_contents) { // TODO(miu): Once render_frame_host() is being set, we should register the // exact RenderFrame requesting the stream, not the main RenderFrame. With // that change, also update // MediaCaptureDevicesDispatcher::ProcessDesktopCaptureAccessRequest(). // http://crbug.com/304341 - content::RenderFrameHost* const main_frame = web_contents()->GetMainFrame(); + content::RenderFrameHost* const main_frame = web_contents->GetMainFrame(); result = content::DesktopStreamsRegistry::GetInstance()->RegisterStream( - main_frame->GetProcess()->GetID(), main_frame->GetRoutingID(), origin_, - source, extension()->name(), content::kRegistryStreamTypeDesktop); + main_frame->GetProcess()->GetID(), main_frame->GetRoutingID(), + url::Origin::Create(origin), source, extension()->name(), + content::kRegistryStreamTypeDesktop); } Options options; diff --git a/chromium/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.h b/chromium/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.h index 798348f9e7a..80232e13338 100644 --- a/chromium/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.h +++ b/chromium/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.h @@ -7,23 +7,22 @@ #include <array> #include <map> +#include <memory> #include <string> #include "base/macros.h" #include "base/memory/singleton.h" #include "chrome/browser/extensions/chrome_extension_function.h" #include "chrome/browser/media/webrtc/desktop_media_list.h" -#include "chrome/browser/media/webrtc/desktop_media_picker.h" +#include "chrome/browser/media/webrtc/desktop_media_picker_controller.h" #include "chrome/browser/media/webrtc/desktop_media_picker_factory.h" #include "chrome/common/extensions/api/desktop_capture.h" -#include "content/public/browser/web_contents_observer.h" #include "url/gurl.h" namespace extensions { class DesktopCaptureChooseDesktopMediaFunctionBase - : public ChromeAsyncExtensionFunction, - public content::WebContentsObserver { + : public ChromeAsyncExtensionFunction { public: // Used to set PickerFactory used to create mock DesktopMediaPicker instances // for tests. Calling tests keep ownership of the factory. Can be called with @@ -41,12 +40,11 @@ class DesktopCaptureChooseDesktopMediaFunctionBase // also be used to determine where to show the picker's UI. // |origin| is the origin for which the stream is created. // |target_name| is the display name of the stream target. - bool Execute( - const std::vector<api::desktop_capture::DesktopCaptureSourceType>& - sources, - content::WebContents* web_contents, - const GURL& origin, - const base::string16 target_name); + bool Execute(const std::vector< + api::desktop_capture::DesktopCaptureSourceType>& sources, + content::WebContents* web_contents, + const GURL& origin, + const base::string16 target_name); // Returns the calling application name to show in the picker. std::string GetCallerDisplayName() const; @@ -54,16 +52,12 @@ class DesktopCaptureChooseDesktopMediaFunctionBase int request_id_; private: - // content::WebContentsObserver overrides. - void WebContentsDestroyed() override; + void OnPickerDialogResults(const GURL& origin, + content::WebContents* web_contents, + const std::string& err, + content::DesktopMediaID source); - void OnPickerDialogResults(content::DesktopMediaID source); - - // URL of page that desktop capture was requested for. - GURL origin_; - - std::unique_ptr<DesktopMediaPickerFactory> picker_factory_; - std::unique_ptr<DesktopMediaPicker> picker_; + std::unique_ptr<DesktopMediaPickerController> picker_controller_; }; class DesktopCaptureCancelChooseDesktopMediaFunctionBase diff --git a/chromium/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chromium/chrome/browser/extensions/api/developer_private/developer_private_api.cc index 6cd0dd1f2f8..d08f651ecdf 100644 --- a/chromium/chrome/browser/extensions/api/developer_private/developer_private_api.cc +++ b/chromium/chrome/browser/extensions/api/developer_private/developer_private_api.cc @@ -20,6 +20,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" +#include "chrome/browser/apps/app_service/app_launch_params.h" #include "chrome/browser/devtools/devtools_window.h" #include "chrome/browser/extensions/api/developer_private/developer_private_mangle.h" #include "chrome/browser/extensions/api/developer_private/entry_picker.h" @@ -46,7 +47,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/apps/app_info_dialog.h" #include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/extensions/app_launch_params.h" #include "chrome/browser/ui/extensions/application_launch.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/extensions/api/developer_private.h" @@ -325,7 +325,7 @@ std::unique_ptr<developer::ProfileInfo> DeveloperPrivateAPI::CreateProfileInfo( info->in_developer_mode = !info->is_supervised && prefs->GetBoolean(prefs::kExtensionsUIDeveloperMode); - info->app_info_dialog_enabled = CanShowAppInfoDialog(); + info->app_info_dialog_enabled = CanPlatformShowAppInfoDialog(); info->can_load_unpacked = ExtensionManagementFactory::GetForBrowserContext(profile) ->HasWhitelistedExtension(); @@ -358,16 +358,7 @@ DeveloperPrivateAPI::DeveloperPrivateAPI(content::BrowserContext* context) } DeveloperPrivateEventRouter::DeveloperPrivateEventRouter(Profile* profile) - : extension_registry_observer_(this), - error_console_observer_(this), - process_manager_observer_(this), - app_window_registry_observer_(this), - warning_service_observer_(this), - extension_prefs_observer_(this), - extension_management_observer_(this), - command_service_observer_(this), - profile_(profile), - event_router_(EventRouter::Get(profile_)) { + : profile_(profile), event_router_(EventRouter::Get(profile_)) { extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); error_console_observer_.Add(ErrorConsole::Get(profile)); process_manager_observer_.Add(ProcessManager::Get(profile)); @@ -955,9 +946,8 @@ DeveloperPrivateUpdateExtensionConfigurationFunction::Run() { return RespondNow(NoArguments()); } -DeveloperPrivateReloadFunction::DeveloperPrivateReloadFunction() - : registry_observer_(this), error_reporter_observer_(this) {} -DeveloperPrivateReloadFunction::~DeveloperPrivateReloadFunction() {} +DeveloperPrivateReloadFunction::DeveloperPrivateReloadFunction() = default; +DeveloperPrivateReloadFunction::~DeveloperPrivateReloadFunction() = default; ExtensionFunction::ResponseAction DeveloperPrivateReloadFunction::Run() { std::unique_ptr<Reload::Params> params(Reload::Params::Create(*args_)); diff --git a/chromium/chrome/browser/extensions/api/developer_private/developer_private_api.h b/chromium/chrome/browser/extensions/api/developer_private/developer_private_api.h index 639cf9e4777..33955e23630 100644 --- a/chromium/chrome/browser/extensions/api/developer_private/developer_private_api.h +++ b/chromium/chrome/browser/extensions/api/developer_private/developer_private_api.h @@ -30,8 +30,11 @@ #include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_function.h" +#include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_prefs_observer.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry_observer.h" +#include "extensions/browser/process_manager.h" #include "extensions/browser/process_manager_observer.h" #include "extensions/browser/warning_service.h" #include "storage/browser/fileapi/file_system_context.h" @@ -45,8 +48,6 @@ namespace extensions { class EventRouter; class ExtensionError; class ExtensionInfoGenerator; -class ExtensionRegistry; -class ProcessManager; namespace api { @@ -144,20 +145,21 @@ class DeveloperPrivateEventRouter : public ExtensionRegistryObserver, std::vector<api::developer_private::ExtensionInfo> infos); ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - extension_registry_observer_; - ScopedObserver<ErrorConsole, ErrorConsole::Observer> error_console_observer_; + extension_registry_observer_{this}; + ScopedObserver<ErrorConsole, ErrorConsole::Observer> error_console_observer_{ + this}; ScopedObserver<ProcessManager, ProcessManagerObserver> - process_manager_observer_; + process_manager_observer_{this}; ScopedObserver<AppWindowRegistry, AppWindowRegistry::Observer> - app_window_registry_observer_; + app_window_registry_observer_{this}; ScopedObserver<WarningService, WarningService::Observer> - warning_service_observer_; + warning_service_observer_{this}; ScopedObserver<ExtensionPrefs, ExtensionPrefsObserver> - extension_prefs_observer_; + extension_prefs_observer_{this}; ScopedObserver<ExtensionManagement, ExtensionManagement::Observer> - extension_management_observer_; + extension_management_observer_{this}; ScopedObserver<CommandService, CommandService::Observer> - command_service_observer_; + command_service_observer_{this}; Profile* profile_; @@ -464,9 +466,9 @@ class DeveloperPrivateReloadFunction : public DeveloperPrivateAPIFunction, base::FilePath reloading_extension_path_; ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - registry_observer_; + registry_observer_{this}; ScopedObserver<LoadErrorReporter, LoadErrorReporter::Observer> - error_reporter_observer_; + error_reporter_observer_{this}; DISALLOW_COPY_AND_ASSIGN(DeveloperPrivateReloadFunction); }; diff --git a/chromium/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc b/chromium/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc index cf68ed7c110..62b206bf7ab 100644 --- a/chromium/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc +++ b/chromium/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc @@ -80,7 +80,7 @@ std::string SiteControlsToString( list.GetList().reserve(controls.size()); for (const auto& control : controls) { std::unique_ptr<base::Value> control_value = control.ToValue(); - list.GetList().push_back(std::move(*control_value)); + list.Append(std::move(*control_value)); } std::string json; diff --git a/chromium/chrome/browser/extensions/api/developer_private/show_permissions_dialog_helper.cc b/chromium/chrome/browser/extensions/api/developer_private/show_permissions_dialog_helper.cc index 4d719aaff50..a81a0674b73 100644 --- a/chromium/chrome/browser/extensions/api/developer_private/show_permissions_dialog_helper.cc +++ b/chromium/chrome/browser/extensions/api/developer_private/show_permissions_dialog_helper.cc @@ -40,7 +40,7 @@ void ShowPermissionsDialogHelper::Show(content::BrowserContext* browser_context, // Show the new-style extensions dialog when it is available. It is currently // unavailable by default on Mac. - if (CanShowAppInfoDialog()) { + if (CanPlatformShowAppInfoDialog()) { if (from_webui) { UMA_HISTOGRAM_ENUMERATION("Apps.AppInfoDialog.Launches", AppInfoLaunchSource::FROM_EXTENSIONS_PAGE, diff --git a/chromium/chrome/browser/extensions/api/device_permissions_manager_unittest.cc b/chromium/chrome/browser/extensions/api/device_permissions_manager_unittest.cc index 095b9e97d3f..b5f3d56bcb8 100644 --- a/chromium/chrome/browser/extensions/api/device_permissions_manager_unittest.cc +++ b/chromium/chrome/browser/extensions/api/device_permissions_manager_unittest.cc @@ -69,10 +69,10 @@ class DevicePermissionsManagerTest : public testing::Test { device3_ = fake_usb_manager_.CreateAndAddDevice(0, 0, "Test Manufacturer", "Test Product", ""); - device::mojom::HidManagerPtr hid_manager_ptr; - fake_hid_manager_.Bind(mojo::MakeRequest(&hid_manager_ptr)); + mojo::PendingRemote<device::mojom::HidManager> hid_manager; + fake_hid_manager_.Bind(hid_manager.InitWithNewPipeAndPassReceiver()); HidDeviceManager::Get(env_->profile()) - ->SetFakeHidManagerForTesting(std::move(hid_manager_ptr)); + ->SetFakeHidManagerForTesting(std::move(hid_manager)); base::RunLoop().RunUntilIdle(); device4_ = fake_hid_manager_.CreateAndAddDevice( diff --git a/chromium/chrome/browser/extensions/api/downloads/downloads_api.cc b/chromium/chrome/browser/extensions/api/downloads/downloads_api.cc index 7ba05fc5f7a..9a908ac71c4 100644 --- a/chromium/chrome/browser/extensions/api/downloads/downloads_api.cc +++ b/chromium/chrome/browser/extensions/api/downloads/downloads_api.cc @@ -70,7 +70,6 @@ #include "extensions/browser/event_router.h" #include "extensions/browser/extension_function_dispatcher.h" #include "extensions/browser/extension_prefs.h" -#include "extensions/browser/extension_registry.h" #include "extensions/browser/notification_types.h" #include "extensions/browser/warning_service.h" #include "extensions/common/permissions/permissions_data.h" @@ -149,6 +148,11 @@ const char kDangerUnwanted[] = "unwanted"; const char kDangerWhitelistedByPolicy[] = "whitelistedByPolicy"; const char kDangerAsyncScanning[] = "asyncScanning"; const char kDangerPasswordProtected[] = "passwordProtected"; +const char kDangerTooLarge[] = "blockedTooLarge"; +const char kDangerSensitiveContentWarning[] = "sensitiveContentWarning"; +const char kDangerSensitiveContentBlock[] = "sensitiveContentBlock"; +const char kDangerDeepScannedSafe[] = "deepScannedSafe"; +const char kDangerDeepScannedOpenedDangerous[] = "deepScannedOpenedDangerous"; const char kDangerUrl[] = "url"; const char kEndTimeKey[] = "endTime"; const char kEndedAfterKey[] = "endedAfter"; @@ -182,13 +186,23 @@ const char kFinalUrlRegexKey[] = "finalUrlRegex"; // Note: Any change to the danger type strings, should be accompanied by a // corresponding change to downloads.json. -const char* const kDangerStrings[] = { - kDangerSafe, kDangerFile, - kDangerUrl, kDangerContent, - kDangerSafe, kDangerUncommon, - kDangerAccepted, kDangerHost, - kDangerUnwanted, kDangerWhitelistedByPolicy, - kDangerAsyncScanning, kDangerPasswordProtected}; +const char* const kDangerStrings[] = {kDangerSafe, + kDangerFile, + kDangerUrl, + kDangerContent, + kDangerSafe, + kDangerUncommon, + kDangerAccepted, + kDangerHost, + kDangerUnwanted, + kDangerWhitelistedByPolicy, + kDangerAsyncScanning, + kDangerPasswordProtected, + kDangerTooLarge, + kDangerSensitiveContentWarning, + kDangerSensitiveContentBlock, + kDangerDeepScannedSafe, + kDangerDeepScannedOpenedDangerous}; static_assert(base::size(kDangerStrings) == download::DOWNLOAD_DANGER_TYPE_MAX, "kDangerStrings should have DOWNLOAD_DANGER_TYPE_MAX elements"); @@ -396,7 +410,7 @@ void InitFilterTypeMap(FilterTypeMap* filter_types_ptr) { AppendFilter(kFinalUrlKey, DownloadQuery::FILTER_URL, &v); AppendFilter(kFinalUrlRegexKey, DownloadQuery::FILTER_URL_REGEX, &v); - *filter_types_ptr = FilterTypeMap(std::move(v), base::KEEP_FIRST_OF_DUPES); + *filter_types_ptr = FilterTypeMap(std::move(v)); } using SortTypeMap = base::flat_map<std::string, DownloadQuery::SortType>; @@ -423,7 +437,7 @@ void InitSortTypeMap(SortTypeMap* sorter_types_ptr) { AppendFilter(kUrlKey, DownloadQuery::SORT_ORIGINAL_URL, &v); AppendFilter(kFinalUrlKey, DownloadQuery::SORT_URL, &v); - *sorter_types_ptr = SortTypeMap(std::move(v), base::KEEP_FIRST_OF_DUPES); + *sorter_types_ptr = SortTypeMap(std::move(v)); } bool IsNotTemporaryDownloadFilter(const DownloadItem& download_item) { @@ -1611,9 +1625,7 @@ void DownloadsGetFileIconFunction::OnIconURLExtracted(const std::string& url) { ExtensionDownloadsEventRouter::ExtensionDownloadsEventRouter( Profile* profile, DownloadManager* manager) - : profile_(profile), - notifier_(manager, this), - extension_registry_observer_(this) { + : profile_(profile), notifier_(manager, this) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(profile_); extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); diff --git a/chromium/chrome/browser/extensions/api/downloads/downloads_api.h b/chromium/chrome/browser/extensions/api/downloads/downloads_api.h index 1f39ba01ffd..d0b6f832269 100644 --- a/chromium/chrome/browser/extensions/api/downloads/downloads_api.h +++ b/chromium/chrome/browser/extensions/api/downloads/downloads_api.h @@ -20,16 +20,13 @@ #include "components/download/public/common/download_path_reservation_tracker.h" #include "content/public/browser/download_manager.h" #include "extensions/browser/event_router.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry_observer.h" #include "extensions/browser/warning_set.h" class DownloadFileIconExtractor; class DownloadOpenPrompt; -namespace extensions { -class ExtensionRegistry; -} - // Functions in the chrome.downloads namespace facilitate // controlling downloads from extensions. See the full API doc at // http://goo.gl/6hO1n @@ -395,7 +392,7 @@ class ExtensionDownloadsEventRouter // Listen to extension unloaded notifications. ScopedObserver<extensions::ExtensionRegistry, extensions::ExtensionRegistryObserver> - extension_registry_observer_; + extension_registry_observer_{this}; DISALLOW_COPY_AND_ASSIGN(ExtensionDownloadsEventRouter); }; diff --git a/chromium/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chromium/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc index 0e2a4d31138..1bfce417f2e 100644 --- a/chromium/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc +++ b/chromium/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc @@ -932,7 +932,7 @@ IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, scoped_refptr<DownloadsOpenFunction> scoped_open(new DownloadsOpenFunction()); scoped_open->set_user_gesture(true); base::Value args_list(base::Value::Type::LIST); - args_list.GetList().emplace_back(static_cast<int>(download_item->GetId())); + args_list.Append(static_cast<int>(download_item->GetId())); scoped_open->SetArgs(std::move(args_list)); scoped_open->set_browser_context(current_browser()->profile()); scoped_open->set_extension(extension()); @@ -1900,31 +1900,31 @@ IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, GoOnTheRecord(); static const char* const kUnsafeHeaders[] = { - "Accept-chArsEt", - "accept-eNcoding", - "coNNection", - "coNteNt-leNgth", - "cooKIE", - "cOOkie2", - "coNteNt-traNsfer-eNcodiNg", - "dAtE", - "ExpEcT", - "hOsT", - "kEEp-aLivE", - "rEfErEr", - "tE", - "trAilER", - "trANsfer-eNcodiNg", - "upGRAde", - "usER-agENt", - "viA", - "pRoxY-", - "sEc-", - "pRoxY-probably-not-evil", - "sEc-probably-not-evil", - "oRiGiN", - "Access-Control-Request-Headers", - "Access-Control-Request-Method", + "Accept-chArsEt", + "accept-eNcoding", + "coNNection", + "coNteNt-leNgth", + "cooKIE", + "cOOkie2", + "dAtE", + "DNT", + "ExpEcT", + "hOsT", + "kEEp-aLivE", + "rEfErEr", + "tE", + "trAilER", + "trANsfer-eNcodiNg", + "upGRAde", + "usER-agENt", + "viA", + "pRoxY-", + "sEc-", + "pRoxY-probably-not-evil", + "sEc-probably-not-evil", + "oRiGiN", + "Access-Control-Request-Headers", + "Access-Control-Request-Method", }; for (size_t index = 0; index < base::size(kUnsafeHeaders); ++index) { diff --git a/chromium/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api.cc b/chromium/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api.cc index 87b1c700975..60af1cbb3f6 100644 --- a/chromium/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api.cc +++ b/chromium/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api.cc @@ -7,6 +7,7 @@ #include "base/values.h" #include "chrome/browser/app_mode/app_mode_utils.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" diff --git a/chromium/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc b/chromium/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc index 9d3f31a0a72..b4f0086533c 100644 --- a/chromium/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc +++ b/chromium/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc @@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/json/json_writer.h" #include "base/path_service.h" -#include "base/strings/stringprintf.h" #include "base/task/post_task.h" #include "base/values.h" #include "chrome/browser/browser_process.h" @@ -15,6 +14,7 @@ #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" #include "chrome/browser/extensions/extension_apitest.h" +#include "chrome/browser/extensions/policy_test_utils.h" #include "chrome/common/chrome_paths.h" #include "chrome/test/base/ui_test_utils.h" #include "chromeos/dbus/session_manager/fake_session_manager_client.h" @@ -24,7 +24,6 @@ #include "components/account_id/account_id.h" #include "components/policy/core/common/cloud/device_management_service.h" #include "components/policy/core/common/mock_configuration_policy_provider.h" -#include "components/policy/policy_constants.h" #include "components/prefs/pref_service.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/browser_task_traits.h" @@ -33,10 +32,7 @@ #include "content/public/test/test_utils.h" #include "extensions/browser/api_test_utils.h" #include "extensions/browser/extension_registry.h" -#include "extensions/browser/test_extension_registry_observer.h" #include "extensions/test/result_catcher.h" -#include "net/test/embedded_test_server/http_request.h" -#include "net/test/embedded_test_server/http_response.h" namespace { @@ -99,34 +95,6 @@ class EnterpriseDeviceAttributesTest set_chromeos_user_ = false; } - // Replace "mock.http" with "127.0.0.1:<port>" on "update_manifest.xml" files. - // Host resolver doesn't work here because the test file doesn't know the - // correct port number. - std::unique_ptr<net::test_server::HttpResponse> InterceptMockHttp( - const net::test_server::HttpRequest& request) { - const std::string kFileNameToIntercept = "update_manifest.xml"; - if (request.GetURL().ExtractFileName() != kFileNameToIntercept) - return nullptr; - - base::FilePath test_data_dir; - base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); - // Remove the leading '/'. - std::string relative_manifest_path = request.GetURL().path().substr(1); - std::string manifest_response; - CHECK(base::ReadFileToString(test_data_dir.Append(relative_manifest_path), - &manifest_response)); - - base::ReplaceSubstringsAfterOffset( - &manifest_response, 0, "mock.http", - embedded_test_server()->host_port_pair().ToString()); - - std::unique_ptr<net::test_server::BasicHttpResponse> response( - new net::test_server::BasicHttpResponse()); - response->set_content_type("text/xml"); - response->set_content(manifest_response); - return response; - } - protected: // ExtensionApiTest void SetUpCommandLine(base::CommandLine* command_line) override { @@ -192,29 +160,6 @@ class EnterpriseDeviceAttributesTest ExtensionApiTest::SetUpOnMainThread(); } - void SetPolicy() { - // Extensions that are force-installed come from an update URL, which - // defaults to the webstore. Use a mock URL for this test with an update - // manifest that includes the crx file of the test extension. - GURL update_manifest_url( - embedded_test_server()->GetURL(kUpdateManifestPath)); - - std::unique_ptr<base::ListValue> forcelist(new base::ListValue); - forcelist->AppendString(base::StringPrintf( - "%s;%s", kTestExtensionID, update_manifest_url.spec().c_str())); - - policy::PolicyMap policy; - policy.Set(policy::key::kExtensionInstallForcelist, - policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_MACHINE, - policy::POLICY_SOURCE_CLOUD, std::move(forcelist), nullptr); - - // Set the policy and wait until the extension is installed. - extensions::TestExtensionRegistryObserver observer( - ExtensionRegistry::Get(profile())); - policy_provider_.UpdateChromePolicy(policy); - observer.WaitForExtensionLoaded(); - } - // Load |page_url| in |browser| and wait for PASSED or FAILED notification. // The functionality of this function is reduced functionality of // RunExtensionSubtest(), but we don't use it here because it requires @@ -248,11 +193,12 @@ class EnterpriseDeviceAttributesTest AccountId::FromUserEmailGaiaId(kAffiliatedUserEmail, kAffiliatedUserGaiaId); + policy::MockConfigurationPolicyProvider policy_provider_; + private: chromeos::ScopedStubInstallAttributes test_install_attributes_{ chromeos::StubInstallAttributes::CreateCloudManaged("fake-domain", "fake-id")}; - policy::MockConfigurationPolicyProvider policy_provider_; policy::DevicePolicyCrosTestHelper test_helper_; chromeos::system::ScopedFakeStatisticsProvider fake_statistics_provider_; }; @@ -262,13 +208,11 @@ IN_PROC_BROWSER_TEST_P(EnterpriseDeviceAttributesTest, PRE_Success) { } IN_PROC_BROWSER_TEST_P(EnterpriseDeviceAttributesTest, Success) { - // Setup |URLLoaderInterceptor|, which is required for force-installing the - // test extension through policy. - embedded_test_server()->RegisterRequestHandler( - base::BindRepeating(&EnterpriseDeviceAttributesTest::InterceptMockHttp, - base::Unretained(this))); + policy_test_utils::SetUpEmbeddedTestServer(embedded_test_server()); ASSERT_TRUE(embedded_test_server()->Start()); - SetPolicy(); + policy_test_utils::SetExtensionInstallForcelistPolicy( + kTestExtensionID, embedded_test_server()->GetURL(kUpdateManifestPath), + profile(), &policy_provider_); EXPECT_EQ(GetParam().affiliated, user_manager::UserManager::Get() ->FindUser(affiliated_account_id_) diff --git a/chromium/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.cc b/chromium/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.cc index 2932c7037d5..dfcc812c94b 100644 --- a/chromium/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.cc +++ b/chromium/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.cc @@ -45,8 +45,7 @@ std::string StringFromVector(const std::vector<uint8_t>& v) { } // namespace EnterprisePlatformKeysInternalGenerateKeyFunction:: - ~EnterprisePlatformKeysInternalGenerateKeyFunction() { -} + ~EnterprisePlatformKeysInternalGenerateKeyFunction() = default; ExtensionFunction::ResponseAction EnterprisePlatformKeysInternalGenerateKeyFunction::Run() { @@ -64,9 +63,7 @@ EnterprisePlatformKeysInternalGenerateKeyFunction::Run() { DCHECK(service); service->GenerateRSAKey( - platform_keys_token_id, - params->modulus_length, - extension_id(), + platform_keys_token_id, params->modulus_length, extension_id(), base::Bind( &EnterprisePlatformKeysInternalGenerateKeyFunction::OnGeneratedKey, this)); @@ -86,8 +83,7 @@ void EnterprisePlatformKeysInternalGenerateKeyFunction::OnGeneratedKey( } EnterprisePlatformKeysGetCertificatesFunction:: - ~EnterprisePlatformKeysGetCertificatesFunction() { -} + ~EnterprisePlatformKeysGetCertificatesFunction() {} ExtensionFunction::ResponseAction EnterprisePlatformKeysGetCertificatesFunction::Run() { @@ -118,8 +114,7 @@ void EnterprisePlatformKeysGetCertificatesFunction::OnGotCertificates( std::unique_ptr<base::ListValue> client_certs(new base::ListValue()); for (net::CertificateList::const_iterator it = certs->begin(); - it != certs->end(); - ++it) { + it != certs->end(); ++it) { base::StringPiece cert_der = net::x509_util::CryptoBufferAsStringPiece((*it)->cert_buffer()); client_certs->Append(std::make_unique<base::Value>( @@ -132,8 +127,7 @@ void EnterprisePlatformKeysGetCertificatesFunction::OnGotCertificates( } EnterprisePlatformKeysImportCertificateFunction:: - ~EnterprisePlatformKeysImportCertificateFunction() { -} + ~EnterprisePlatformKeysImportCertificateFunction() {} ExtensionFunction::ResponseAction EnterprisePlatformKeysImportCertificateFunction::Run() { @@ -157,8 +151,7 @@ EnterprisePlatformKeysImportCertificateFunction::Run() { return RespondNow(Error(kEnterprisePlatformErrorInvalidX509Cert)); chromeos::platform_keys::ImportCertificate( - platform_keys_token_id, - cert_x509, + platform_keys_token_id, cert_x509, base::Bind(&EnterprisePlatformKeysImportCertificateFunction:: OnImportedCertificate, this), @@ -176,8 +169,7 @@ void EnterprisePlatformKeysImportCertificateFunction::OnImportedCertificate( } EnterprisePlatformKeysRemoveCertificateFunction:: - ~EnterprisePlatformKeysRemoveCertificateFunction() { -} + ~EnterprisePlatformKeysRemoveCertificateFunction() {} ExtensionFunction::ResponseAction EnterprisePlatformKeysRemoveCertificateFunction::Run() { @@ -201,8 +193,7 @@ EnterprisePlatformKeysRemoveCertificateFunction::Run() { return RespondNow(Error(kEnterprisePlatformErrorInvalidX509Cert)); chromeos::platform_keys::RemoveCertificate( - platform_keys_token_id, - cert_x509, + platform_keys_token_id, cert_x509, base::Bind(&EnterprisePlatformKeysRemoveCertificateFunction:: OnRemovedCertificate, this), @@ -220,8 +211,7 @@ void EnterprisePlatformKeysRemoveCertificateFunction::OnRemovedCertificate( } EnterprisePlatformKeysInternalGetTokensFunction:: - ~EnterprisePlatformKeysInternalGetTokensFunction() { -} + ~EnterprisePlatformKeysInternalGetTokensFunction() {} ExtensionFunction::ResponseAction EnterprisePlatformKeysInternalGetTokensFunction::Run() { @@ -246,8 +236,7 @@ void EnterprisePlatformKeysInternalGetTokensFunction::OnGotTokens( std::vector<std::string> token_ids; for (std::vector<std::string>::const_iterator it = platform_keys_token_ids->begin(); - it != platform_keys_token_ids->end(); - ++it) { + it != platform_keys_token_ids->end(); ++it) { std::string token_id = platform_keys::PlatformKeysTokenIdToApiId(*it); if (token_id.empty()) { Respond(Error(kEnterprisePlatformErrorInternal)); @@ -260,13 +249,7 @@ void EnterprisePlatformKeysInternalGetTokensFunction::OnGotTokens( } EnterprisePlatformKeysChallengeMachineKeyFunction:: - EnterprisePlatformKeysChallengeMachineKeyFunction() - : default_impl_(new EPKPChallengeMachineKey), impl_(default_impl_.get()) {} - -EnterprisePlatformKeysChallengeMachineKeyFunction:: - EnterprisePlatformKeysChallengeMachineKeyFunction( - EPKPChallengeMachineKey* impl_for_testing) - : impl_(impl_for_testing) {} + EnterprisePlatformKeysChallengeMachineKeyFunction() = default; EnterprisePlatformKeysChallengeMachineKeyFunction:: ~EnterprisePlatformKeysChallengeMachineKeyFunction() = default; @@ -276,39 +259,32 @@ EnterprisePlatformKeysChallengeMachineKeyFunction::Run() { std::unique_ptr<api_epk::ChallengeMachineKey::Params> params( api_epk::ChallengeMachineKey::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params); - ChallengeKeyCallback callback = base::Bind( + chromeos::attestation::TpmChallengeKeyCallback callback = base::BindOnce( &EnterprisePlatformKeysChallengeMachineKeyFunction::OnChallengedKey, this); // base::Unretained is safe on impl_ since its life-cycle matches |this| and // |callback| holds a reference to |this|. - base::Closure task = - base::Bind(&EPKPChallengeMachineKey::Run, base::Unretained(impl_), - scoped_refptr<ExtensionFunction>(this), callback, - StringFromVector(params->challenge), - params->register_key ? *params->register_key : false); - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, task); + base::OnceClosure task = base::BindOnce( + &EPKPChallengeKey::Run, base::Unretained(&impl_), + chromeos::attestation::KEY_DEVICE, scoped_refptr<ExtensionFunction>(this), + std::move(callback), StringFromVector(params->challenge), + params->register_key ? *params->register_key : false); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, std::move(task)); return RespondLater(); } void EnterprisePlatformKeysChallengeMachineKeyFunction::OnChallengedKey( - bool success, - const std::string& data) { - if (success) { - Respond(ArgumentList( - api_epk::ChallengeMachineKey::Results::Create(VectorFromString(data)))); + const chromeos::attestation::TpmChallengeKeyResult& result) { + if (result.is_success) { + Respond(ArgumentList(api_epk::ChallengeMachineKey::Results::Create( + VectorFromString(result.data)))); } else { - Respond(Error(data)); + Respond(Error(result.error_message)); } } EnterprisePlatformKeysChallengeUserKeyFunction:: - EnterprisePlatformKeysChallengeUserKeyFunction() - : default_impl_(new EPKPChallengeUserKey), impl_(default_impl_.get()) {} - -EnterprisePlatformKeysChallengeUserKeyFunction:: - EnterprisePlatformKeysChallengeUserKeyFunction( - EPKPChallengeUserKey* impl_for_testing) - : impl_(impl_for_testing) {} + EnterprisePlatformKeysChallengeUserKeyFunction() = default; EnterprisePlatformKeysChallengeUserKeyFunction:: ~EnterprisePlatformKeysChallengeUserKeyFunction() = default; @@ -318,26 +294,26 @@ EnterprisePlatformKeysChallengeUserKeyFunction::Run() { std::unique_ptr<api_epk::ChallengeUserKey::Params> params( api_epk::ChallengeUserKey::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params); - ChallengeKeyCallback callback = base::Bind( + chromeos::attestation::TpmChallengeKeyCallback callback = base::Bind( &EnterprisePlatformKeysChallengeUserKeyFunction::OnChallengedKey, this); // base::Unretained is safe on impl_ since its life-cycle matches |this| and // |callback| holds a reference to |this|. - base::Closure task = - base::Bind(&EPKPChallengeUserKey::Run, base::Unretained(impl_), - scoped_refptr<ExtensionFunction>(this), callback, - StringFromVector(params->challenge), params->register_key); - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, task); + base::OnceClosure task = base::BindOnce( + &EPKPChallengeKey::Run, base::Unretained(&impl_), + chromeos::attestation::KEY_USER, scoped_refptr<ExtensionFunction>(this), + std::move(callback), StringFromVector(params->challenge), + params->register_key); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, std::move(task)); return RespondLater(); } void EnterprisePlatformKeysChallengeUserKeyFunction::OnChallengedKey( - bool success, - const std::string& data) { - if (success) { - Respond(ArgumentList( - api_epk::ChallengeUserKey::Results::Create(VectorFromString(data)))); + const chromeos::attestation::TpmChallengeKeyResult& result) { + if (result.is_success) { + Respond(ArgumentList(api_epk::ChallengeUserKey::Results::Create( + VectorFromString(result.data)))); } else { - Respond(Error(data)); + Respond(Error(result.error_message)); } } diff --git a/chromium/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h b/chromium/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h index 9ec384a2ef3..598990b14ed 100644 --- a/chromium/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h +++ b/chromium/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h @@ -15,8 +15,8 @@ namespace net { class X509Certificate; -typedef std::vector<scoped_refptr<X509Certificate> > CertificateList; -} +using CertificateList = std::vector<scoped_refptr<X509Certificate>>; +} // namespace net namespace extensions { @@ -96,20 +96,16 @@ class EnterprisePlatformKeysChallengeMachineKeyFunction : public ExtensionFunction { public: EnterprisePlatformKeysChallengeMachineKeyFunction(); - explicit EnterprisePlatformKeysChallengeMachineKeyFunction( - EPKPChallengeMachineKey* impl_for_testing); private: ~EnterprisePlatformKeysChallengeMachineKeyFunction() override; ResponseAction Run() override; - // Called when the challenge operation is complete. If the operation succeeded - // |success| will be true and |data| will contain the challenge response data. - // Otherwise |success| will be false and |data| is an error message. - void OnChallengedKey(bool success, const std::string& data); + // Called when the challenge operation is complete. + void OnChallengedKey( + const chromeos::attestation::TpmChallengeKeyResult& result); - std::unique_ptr<EPKPChallengeMachineKey> default_impl_; - EPKPChallengeMachineKey* impl_; + EPKPChallengeKey impl_; DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.challengeMachineKey", ENTERPRISE_PLATFORMKEYS_CHALLENGEMACHINEKEY) @@ -119,20 +115,16 @@ class EnterprisePlatformKeysChallengeUserKeyFunction : public ExtensionFunction { public: EnterprisePlatformKeysChallengeUserKeyFunction(); - explicit EnterprisePlatformKeysChallengeUserKeyFunction( - EPKPChallengeUserKey* impl_for_testing); private: ~EnterprisePlatformKeysChallengeUserKeyFunction() override; ResponseAction Run() override; - // Called when the challenge operation is complete. If the operation succeeded - // |success| will be true and |data| will contain the challenge response data. - // Otherwise |success| will be false and |data| is an error message. - void OnChallengedKey(bool success, const std::string& data); + // Called when the challenge operation is complete. + void OnChallengedKey( + const chromeos::attestation::TpmChallengeKeyResult& result); - std::unique_ptr<EPKPChallengeUserKey> default_impl_; - EPKPChallengeUserKey* impl_; + EPKPChallengeKey impl_; DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.challengeUserKey", ENTERPRISE_PLATFORMKEYS_CHALLENGEUSERKEY) diff --git a/chromium/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc b/chromium/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc index bffca7db092..386feaea2a6 100644 --- a/chromium/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc +++ b/chromium/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc @@ -4,170 +4,71 @@ #include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h" -#include <string> +#include <utility> -#include "base/bind.h" -#include "base/location.h" -#include "base/memory/ptr_util.h" -#include "base/strings/stringprintf.h" -#include "base/threading/thread_task_runner_handle.h" #include "base/values.h" +#include "chrome/browser/chromeos/attestation/mock_tpm_challenge_key.h" #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" -#include "chrome/browser/chromeos/settings/cros_settings.h" -#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h" #include "chrome/browser/extensions/extension_function_test_utils.h" #include "chrome/browser/signin/identity_manager_factory.h" -#include "chrome/browser/ui/browser.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/browser_with_test_window_test.h" -#include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile_manager.h" -#include "chromeos/attestation/mock_attestation_flow.h" -#include "chromeos/cryptohome/async_method_caller.h" -#include "chromeos/cryptohome/cryptohome_parameters.h" -#include "chromeos/cryptohome/mock_async_method_caller.h" -#include "chromeos/dbus/constants/attestation_constants.h" -#include "chromeos/dbus/cryptohome/fake_cryptohome_client.h" -#include "chromeos/dbus/dbus_method_call_status.h" -#include "chromeos/tpm/stub_install_attributes.h" -#include "components/account_id/account_id.h" -#include "components/policy/core/common/cloud/cloud_policy_constants.h" -#include "components/prefs/pref_service.h" +#include "components/signin/public/identity_manager/identity_manager.h" #include "components/signin/public/identity_manager/identity_test_utils.h" #include "components/user_manager/scoped_user_manager.h" #include "extensions/common/extension_builder.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/cros_system_api/dbus/service_constants.h" -using testing::_; using testing::Invoke; using testing::NiceMock; -using testing::Return; -using testing::WithArgs; namespace utils = extension_function_test_utils; namespace extensions { namespace { -// Certificate errors as reported to the calling extension. -const int kDBusError = 1; -const int kUserRejected = 2; -const int kGetCertificateFailed = 3; -const int kResetRequired = 4; - const char kUserEmail[] = "test@google.com"; -void RegisterKeyCallbackTrue( - chromeos::attestation::AttestationKeyType key_type, - const cryptohome::Identification& user_id, - const std::string& key_name, - const cryptohome::AsyncMethodCaller::Callback& callback) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(callback, true, cryptohome::MOUNT_ERROR_NONE)); -} - -void RegisterKeyCallbackFalse( - chromeos::attestation::AttestationKeyType key_type, - const cryptohome::Identification& user_id, - const std::string& key_name, - const cryptohome::AsyncMethodCaller::Callback& callback) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(callback, false, cryptohome::MOUNT_ERROR_NONE)); -} - -void SignChallengeCallbackTrue( - chromeos::attestation::AttestationKeyType key_type, - const cryptohome::Identification& user_id, - const std::string& key_name, - const std::string& domain, - const std::string& device_id, - chromeos::attestation::AttestationChallengeOptions options, - const std::string& challenge, - const std::string& key_name_for_spkac, - const cryptohome::AsyncMethodCaller::DataCallback& callback) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(callback, true, "response")); -} - -void SignChallengeCallbackFalse( +void FakeRunCheckNotRegister( chromeos::attestation::AttestationKeyType key_type, - const cryptohome::Identification& user_id, - const std::string& key_name, - const std::string& domain, - const std::string& device_id, - chromeos::attestation::AttestationChallengeOptions options, + Profile* profile, + chromeos::attestation::TpmChallengeKeyCallback callback, const std::string& challenge, - const std::string& key_name_for_spkac, - const cryptohome::AsyncMethodCaller::DataCallback& callback) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(callback, false, "")); -} - -void GetCertificateCallbackTrue( - chromeos::attestation::AttestationCertificateProfile certificate_profile, - const AccountId& account_id, - const std::string& request_origin, - bool force_new_key, - const std::string& key_name, - const chromeos::attestation::AttestationFlow::CertificateCallback& - callback) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(callback, chromeos::attestation::ATTESTATION_SUCCESS, - "certificate")); -} - -void GetCertificateCallbackFalse( - chromeos::attestation::AttestationCertificateProfile certificate_profile, - const AccountId& account_id, - const std::string& request_origin, - bool force_new_key, - const std::string& key_name, - const chromeos::attestation::AttestationFlow::CertificateCallback& - callback) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(callback, - chromeos::attestation::ATTESTATION_UNSPECIFIED_FAILURE, - "")); + bool register_key, + const std::string& key_name_for_spkac) { + EXPECT_FALSE(register_key); + std::move(callback).Run( + chromeos::attestation::TpmChallengeKeyResult::MakeResult("response")); } class EPKChallengeKeyTestBase : public BrowserWithTestWindowTest { protected: EPKChallengeKeyTestBase() - : settings_helper_(false), - extension_(ExtensionBuilder("Test").Build()), + : extension_(ExtensionBuilder("Test").Build()), fake_user_manager_(new chromeos::FakeChromeUserManager), user_manager_enabler_(base::WrapUnique(fake_user_manager_)) { - // Set up the default behavior of mocks. - ON_CALL(mock_async_method_caller_, TpmAttestationRegisterKey(_, _, _, _)) - .WillByDefault(Invoke(RegisterKeyCallbackTrue)); - ON_CALL(mock_async_method_caller_, - TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _, _)) - .WillByDefault(Invoke(SignChallengeCallbackTrue)); - ON_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _)) - .WillByDefault(Invoke(GetCertificateCallbackTrue)); - stub_install_attributes_.SetCloudManaged("google.com", "device_id"); - - settings_helper_.ReplaceDeviceSettingsProviderWithStub(); - settings_helper_.SetBoolean(chromeos::kDeviceAttestationEnabled, true); } void SetUp() override { BrowserWithTestWindowTest::SetUp(); - - // Set the user preferences. prefs_ = browser()->profile()->GetPrefs(); - base::ListValue whitelist; - whitelist.AppendString(extension_->id()); - prefs_->Set(prefs::kAttestationExtensionWhitelist, whitelist); - SetAuthenticatedUser(); } + void SetMockTpmChallenger() { + auto mock_tpm_challenge_key = std::make_unique< + NiceMock<chromeos::attestation::MockTpmChallengeKey>>(); + // Will be used with EXPECT_CALL. + mock_tpm_challenge_key_ = mock_tpm_challenge_key.get(); + mock_tpm_challenge_key->EnableFake(); + // transfer ownership inside factory + chromeos::attestation::TpmChallengeKeyFactory::SetForTesting( + std::move(mock_tpm_challenge_key)); + } + // This will be called by BrowserWithTestWindowTest::SetUp(); TestingProfile* CreateProfile() override { fake_user_manager_->AddUserWithAffiliation( @@ -205,8 +106,8 @@ class EPKChallengeKeyTestBase : public BrowserWithTestWindowTest { function->set_has_callback(true); utils::RunFunction(function, std::move(args), browser, extensions::api_test_utils::NONE); - EXPECT_TRUE(function->GetError().empty()) << "Unexpected error: " - << function->GetError(); + EXPECT_TRUE(function->GetError().empty()) + << "Unexpected error: " << function->GetError(); const base::Value* single_result = NULL; if (function->GetResultList() != NULL && function->GetResultList()->Get(0, &single_result)) { @@ -215,33 +116,27 @@ class EPKChallengeKeyTestBase : public BrowserWithTestWindowTest { return NULL; } - chromeos::FakeCryptohomeClient cryptohome_client_; - NiceMock<cryptohome::MockAsyncMethodCaller> mock_async_method_caller_; - NiceMock<chromeos::attestation::MockAttestationFlow> mock_attestation_flow_; - chromeos::ScopedCrosSettingsTestHelper settings_helper_; scoped_refptr<const extensions::Extension> extension_; chromeos::StubInstallAttributes stub_install_attributes_; // fake_user_manager_ is owned by user_manager_enabler_. - chromeos::FakeChromeUserManager* fake_user_manager_; + chromeos::FakeChromeUserManager* fake_user_manager_ = nullptr; user_manager::ScopedUserManager user_manager_enabler_; PrefService* prefs_ = nullptr; + chromeos::attestation::MockTpmChallengeKey* mock_tpm_challenge_key_ = nullptr; }; class EPKChallengeMachineKeyTest : public EPKChallengeKeyTestBase { protected: EPKChallengeMachineKeyTest() - : impl_(&cryptohome_client_, - &mock_async_method_caller_, - &mock_attestation_flow_, - &stub_install_attributes_), - func_(new EnterprisePlatformKeysChallengeMachineKeyFunction(&impl_)) { + : func_(new EnterprisePlatformKeysChallengeMachineKeyFunction()) { func_->set_extension(extension_.get()); } // Returns an error string for the given code. std::string GetCertificateError(int error_code) { return base::StringPrintf( - EPKPChallengeMachineKey::kGetCertificateFailedError, error_code); + chromeos::attestation::TpmChallengeKeyImpl::kGetCertificateFailedError, + error_code); } std::unique_ptr<base::ListValue> CreateArgs() { @@ -266,170 +161,51 @@ class EPKChallengeMachineKeyTest : public EPKChallengeKeyTestBase { return args; } - EPKPChallengeMachineKey impl_; scoped_refptr<EnterprisePlatformKeysChallengeMachineKeyFunction> func_; base::ListValue args_; }; -TEST_F(EPKChallengeMachineKeyTest, NonEnterpriseDevice) { - stub_install_attributes_.SetConsumerOwned(); - - EXPECT_EQ(EPKPChallengeMachineKey::kNonEnterpriseDeviceError, - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); -} - TEST_F(EPKChallengeMachineKeyTest, ExtensionNotWhitelisted) { base::ListValue empty_whitelist; prefs_->Set(prefs::kAttestationExtensionWhitelist, empty_whitelist); - EXPECT_EQ(EPKPChallengeKeyBase::kExtensionNotWhitelistedError, - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); -} - -TEST_F(EPKChallengeMachineKeyTest, DevicePolicyDisabled) { - settings_helper_.SetBoolean(chromeos::kDeviceAttestationEnabled, false); - - EXPECT_EQ(EPKPChallengeKeyBase::kDevicePolicyDisabledError, + EXPECT_EQ(EPKPChallengeKey::kExtensionNotWhitelistedError, RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); } -TEST_F(EPKChallengeMachineKeyTest, DoesKeyExistDbusFailed) { - cryptohome_client_.set_tpm_attestation_does_key_exist_should_succeed(false); - - EXPECT_EQ(GetCertificateError(kDBusError), - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); -} - -TEST_F(EPKChallengeMachineKeyTest, GetCertificateFailed) { - EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _)) - .WillRepeatedly(Invoke(GetCertificateCallbackFalse)); - - EXPECT_EQ(GetCertificateError(kGetCertificateFailed), - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); -} - -TEST_F(EPKChallengeMachineKeyTest, SignChallengeFailed) { - EXPECT_CALL(mock_async_method_caller_, - TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _, _)) - .WillRepeatedly(Invoke(SignChallengeCallbackFalse)); - - EXPECT_EQ(EPKPChallengeKeyBase::kSignChallengeFailedError, - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); -} - -TEST_F(EPKChallengeMachineKeyTest, KeyRegistrationFailed) { - EXPECT_CALL(mock_async_method_caller_, TpmAttestationRegisterKey(_, _, _, _)) - .WillRepeatedly(Invoke(RegisterKeyCallbackFalse)); - - EXPECT_EQ( - EPKPChallengeMachineKey::kKeyRegistrationFailedError, - RunFunctionAndReturnError(func_.get(), CreateArgsRegister(), browser())); -} - -TEST_F(EPKChallengeMachineKeyTest, KeyExists) { - cryptohome_client_.SetTpmAttestationDeviceCertificate("attest-ent-machine", - std::string()); - - // GetCertificate must not be called if the key exists. - EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _)) - .Times(0); - - EXPECT_TRUE(utils::RunFunction(func_.get(), CreateArgs(), browser(), - extensions::api_test_utils::NONE)); -} - -TEST_F(EPKChallengeMachineKeyTest, KeyNotRegisteredByDefault) { - EXPECT_CALL(mock_async_method_caller_, TpmAttestationRegisterKey(_, _, _, _)) - .Times(0); - - EXPECT_TRUE(utils::RunFunction(func_.get(), CreateArgs(), browser(), - extensions::api_test_utils::NONE)); -} - -TEST_F(EPKChallengeMachineKeyTest, KeyNotRegistered) { - EXPECT_CALL(mock_async_method_caller_, TpmAttestationRegisterKey(_, _, _, _)) - .Times(0); - - EXPECT_TRUE(utils::RunFunction(func_.get(), CreateArgsNoRegister(), browser(), - extensions::api_test_utils::NONE)); -} - TEST_F(EPKChallengeMachineKeyTest, Success) { - // GetCertificate must be called exactly once. - EXPECT_CALL(mock_attestation_flow_, - GetCertificate( - chromeos::attestation::PROFILE_ENTERPRISE_MACHINE_CERTIFICATE, - _, _, _, _, _)) - .Times(1); - // SignEnterpriseChallenge must be called exactly once. - EXPECT_CALL(mock_async_method_caller_, - TpmAttestationSignEnterpriseChallenge( - chromeos::attestation::KEY_DEVICE, - cryptohome::Identification(), "attest-ent-machine", - "google.com", "device_id", _, "challenge", _, _)) - .Times(1); + SetMockTpmChallenger(); + + base::Value whitelist(base::Value::Type::LIST); + whitelist.Append(extension_->id()); + prefs_->Set(prefs::kAttestationExtensionWhitelist, whitelist); std::unique_ptr<base::Value> value( RunFunctionAndReturnSingleResult(func_.get(), CreateArgs(), browser())); ASSERT_TRUE(value->is_blob()); - EXPECT_EQ("response", - std::string(value->GetBlob().begin(), value->GetBlob().end())); + std::string response(value->GetBlob().begin(), value->GetBlob().end()); + EXPECT_EQ("response", response); } -TEST_F(EPKChallengeMachineKeyTest, KeyRegisteredSuccess) { - std::string key_name_for_spkac = "attest-ent-machine-" + extension_->id(); - // GetCertificate must be called exactly once. - EXPECT_CALL(mock_attestation_flow_, - GetCertificate( - chromeos::attestation::PROFILE_ENTERPRISE_MACHINE_CERTIFICATE, - _, _, _, _, _)) - .Times(1); - // TpmAttestationRegisterKey must be called exactly once. - EXPECT_CALL(mock_async_method_caller_, - TpmAttestationRegisterKey(chromeos::attestation::KEY_DEVICE, - _ /* Unused by the API. */, - key_name_for_spkac, _)) - .Times(1); - // SignEnterpriseChallenge must be called exactly once. - EXPECT_CALL( - mock_async_method_caller_, - TpmAttestationSignEnterpriseChallenge( - chromeos::attestation::KEY_DEVICE, cryptohome::Identification(), - "attest-ent-machine", "google.com", "device_id", _, "challenge", - key_name_for_spkac, _)) - .Times(1); - - std::unique_ptr<base::Value> value(RunFunctionAndReturnSingleResult( - func_.get(), CreateArgsRegister(), browser())); - - ASSERT_TRUE(value->is_blob()); - EXPECT_EQ("response", - std::string(value->GetBlob().begin(), value->GetBlob().end())); -} +TEST_F(EPKChallengeMachineKeyTest, KeyNotRegisteredByDefault) { + SetMockTpmChallenger(); -TEST_F(EPKChallengeMachineKeyTest, AttestationNotPrepared) { - cryptohome_client_.set_tpm_attestation_is_prepared(false); + base::ListValue whitelist; + whitelist.AppendString(extension_->id()); + prefs_->Set(prefs::kAttestationExtensionWhitelist, whitelist); - EXPECT_EQ(GetCertificateError(kResetRequired), - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); -} + EXPECT_CALL(*mock_tpm_challenge_key_, Run) + .WillOnce(Invoke(FakeRunCheckNotRegister)); -TEST_F(EPKChallengeMachineKeyTest, AttestationPreparedDbusFailed) { - cryptohome_client_.SetServiceIsAvailable(false); - - EXPECT_EQ(GetCertificateError(kDBusError), - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); + EXPECT_TRUE(utils::RunFunction(func_.get(), CreateArgs(), browser(), + extensions::api_test_utils::NONE)); } class EPKChallengeUserKeyTest : public EPKChallengeKeyTestBase { protected: EPKChallengeUserKeyTest() - : impl_(&cryptohome_client_, - &mock_async_method_caller_, - &mock_attestation_flow_, - &stub_install_attributes_), - func_(new EnterprisePlatformKeysChallengeUserKeyFunction(&impl_)) { + : func_(new EnterprisePlatformKeysChallengeUserKeyFunction()) { func_->set_extension(extension_.get()); } @@ -440,12 +216,6 @@ class EPKChallengeUserKeyTest : public EPKChallengeKeyTestBase { prefs_->SetBoolean(prefs::kAttestationEnabled, true); } - // Returns an error string for the given code. - std::string GetCertificateError(int error_code) { - return base::StringPrintf(EPKPChallengeUserKey::kGetCertificateFailedError, - error_code); - } - std::unique_ptr<base::ListValue> CreateArgs() { return CreateArgsInternal(true); } @@ -461,183 +231,15 @@ class EPKChallengeUserKeyTest : public EPKChallengeKeyTestBase { return args; } - EPKPChallengeUserKey impl_; + EPKPChallengeKey impl_; scoped_refptr<EnterprisePlatformKeysChallengeUserKeyFunction> func_; }; -TEST_F(EPKChallengeUserKeyTest, UserPolicyDisabled) { - prefs_->SetBoolean(prefs::kAttestationEnabled, false); - - EXPECT_EQ(EPKPChallengeUserKey::kUserPolicyDisabledError, - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); -} - TEST_F(EPKChallengeUserKeyTest, ExtensionNotWhitelisted) { base::ListValue empty_whitelist; prefs_->Set(prefs::kAttestationExtensionWhitelist, empty_whitelist); - EXPECT_EQ(EPKPChallengeKeyBase::kExtensionNotWhitelistedError, - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); -} - -TEST_F(EPKChallengeUserKeyTest, DevicePolicyDisabled) { - settings_helper_.SetBoolean(chromeos::kDeviceAttestationEnabled, false); - - EXPECT_EQ(EPKPChallengeKeyBase::kDevicePolicyDisabledError, - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); -} - -TEST_F(EPKChallengeUserKeyTest, DoesKeyExistDbusFailed) { - cryptohome_client_.set_tpm_attestation_does_key_exist_should_succeed(false); - - EXPECT_EQ(GetCertificateError(kDBusError), - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); -} - -TEST_F(EPKChallengeUserKeyTest, GetCertificateFailed) { - EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _)) - .WillRepeatedly(Invoke(GetCertificateCallbackFalse)); - - EXPECT_EQ(GetCertificateError(kGetCertificateFailed), - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); -} - -TEST_F(EPKChallengeUserKeyTest, SignChallengeFailed) { - EXPECT_CALL(mock_async_method_caller_, - TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _, _)) - .WillRepeatedly(Invoke(SignChallengeCallbackFalse)); - - EXPECT_EQ(EPKPChallengeKeyBase::kSignChallengeFailedError, - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); -} - -TEST_F(EPKChallengeUserKeyTest, KeyRegistrationFailed) { - EXPECT_CALL(mock_async_method_caller_, TpmAttestationRegisterKey(_, _, _, _)) - .WillRepeatedly(Invoke(RegisterKeyCallbackFalse)); - - EXPECT_EQ(EPKPChallengeUserKey::kKeyRegistrationFailedError, - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); -} - -TEST_F(EPKChallengeUserKeyTest, KeyExists) { - cryptohome_client_.SetTpmAttestationUserCertificate( - cryptohome::CreateAccountIdentifierFromAccountId( - AccountId::FromUserEmail(kUserEmail)), - "attest-ent-user", std::string()); - // GetCertificate must not be called if the key exists. - EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _)) - .Times(0); - - EXPECT_TRUE(utils::RunFunction(func_.get(), CreateArgs(), browser(), - extensions::api_test_utils::NONE)); -} - -TEST_F(EPKChallengeUserKeyTest, KeyNotRegistered) { - EXPECT_CALL(mock_async_method_caller_, TpmAttestationRegisterKey(_, _, _, _)) - .Times(0); - - EXPECT_TRUE(utils::RunFunction(func_.get(), CreateArgsNoRegister(), browser(), - extensions::api_test_utils::NONE)); -} - -TEST_F(EPKChallengeUserKeyTest, PersonalDevice) { - stub_install_attributes_.SetConsumerOwned(); - - // Currently personal devices are not supported. - EXPECT_EQ(GetCertificateError(kUserRejected), - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); -} - -TEST_F(EPKChallengeUserKeyTest, Success) { - // GetCertificate must be called exactly once. - EXPECT_CALL( - mock_attestation_flow_, - GetCertificate(chromeos::attestation::PROFILE_ENTERPRISE_USER_CERTIFICATE, - _, _, _, _, _)) - .Times(1); - const cryptohome::Identification cryptohome_id( - AccountId::FromUserEmail(kUserEmail)); - // SignEnterpriseChallenge must be called exactly once. - EXPECT_CALL( - mock_async_method_caller_, - TpmAttestationSignEnterpriseChallenge( - chromeos::attestation::KEY_USER, cryptohome_id, "attest-ent-user", - kUserEmail, "device_id", _, "challenge", _, _)) - .Times(1); - // RegisterKey must be called exactly once. - EXPECT_CALL(mock_async_method_caller_, - TpmAttestationRegisterKey(chromeos::attestation::KEY_USER, - cryptohome_id, "attest-ent-user", _)) - .Times(1); - - std::unique_ptr<base::Value> value( - RunFunctionAndReturnSingleResult(func_.get(), CreateArgs(), browser())); - - ASSERT_TRUE(value->is_blob()); - EXPECT_EQ("response", - std::string(value->GetBlob().begin(), value->GetBlob().end())); -} - -TEST_F(EPKChallengeUserKeyTest, AttestationNotPrepared) { - cryptohome_client_.set_tpm_attestation_is_prepared(false); - - EXPECT_EQ(GetCertificateError(kResetRequired), - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); -} - -TEST_F(EPKChallengeUserKeyTest, AttestationPreparedDbusFailed) { - cryptohome_client_.SetServiceIsAvailable(false); - - EXPECT_EQ(GetCertificateError(kDBusError), - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); -} - -class EPKChallengeMachineKeyUnmanagedUserTest - : public EPKChallengeMachineKeyTest { - protected: - void SetAuthenticatedUser() override { - signin::MakePrimaryAccountAvailable( - IdentityManagerFactory::GetForProfile(browser()->profile()), - account_id_.GetUserEmail()); - } - - TestingProfile* CreateProfile() override { - fake_user_manager_->AddUser(account_id_); - return profile_manager()->CreateTestingProfile(account_id_.GetUserEmail()); - } - - const std::string email = "test@chromium.com"; - const AccountId account_id_ = - AccountId::FromUserEmailGaiaId(email, - signin::GetTestGaiaIdForEmail(email)); -}; - -TEST_F(EPKChallengeMachineKeyUnmanagedUserTest, UserNotManaged) { - EXPECT_EQ(EPKPChallengeKeyBase::kUserNotManaged, - RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); -} - -class EPKChallengeUserKeyUnmanagedUserTest : public EPKChallengeUserKeyTest { - protected: - void SetAuthenticatedUser() override { - signin::MakePrimaryAccountAvailable( - IdentityManagerFactory::GetForProfile(browser()->profile()), - account_id_.GetUserEmail()); - } - - TestingProfile* CreateProfile() override { - fake_user_manager_->AddUser(account_id_); - return profile_manager()->CreateTestingProfile(account_id_.GetUserEmail()); - } - - const std::string email = "test@chromium.com"; - const AccountId account_id_ = - AccountId::FromUserEmailGaiaId(email, - signin::GetTestGaiaIdForEmail(email)); -}; - -TEST_F(EPKChallengeUserKeyUnmanagedUserTest, UserNotManaged) { - EXPECT_EQ(EPKPChallengeKeyBase::kUserNotManaged, + EXPECT_EQ(EPKPChallengeKey::kExtensionNotWhitelistedError, RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); } diff --git a/chromium/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc b/chromium/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc index aa1e7cd62db..36988ba6dac 100644 --- a/chromium/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc +++ b/chromium/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc @@ -11,23 +11,18 @@ #include "base/path_service.h" #include "base/run_loop.h" #include "base/stl_util.h" -#include "base/strings/stringprintf.h" #include "base/task/post_task.h" #include "chrome/browser/extensions/api/platform_keys/platform_keys_test_base.h" +#include "chrome/browser/extensions/policy_test_utils.h" #include "chrome/browser/net/nss_context.h" #include "chrome/common/chrome_paths.h" -#include "components/policy/core/common/policy_map.h" -#include "components/policy/policy_constants.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/content_switches.h" #include "crypto/nss_util_internal.h" #include "crypto/scoped_test_system_nss_key_slot.h" #include "extensions/browser/extension_registry.h" -#include "extensions/browser/test_extension_registry_observer.h" #include "net/cert/nss_cert_database.h" -#include "net/test/embedded_test_server/http_request.h" -#include "net/test/embedded_test_server/http_response.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -168,9 +163,7 @@ class EnterprisePlatformKeysTest } void SetUpOnMainThread() override { - embedded_test_server()->RegisterRequestHandler( - base::BindRepeating(&EnterprisePlatformKeysTest::InterceptMockHttp, - base::Unretained(this))); + policy_test_utils::SetUpEmbeddedTestServer(embedded_test_server()); PlatformKeysTestBase::SetUpOnMainThread(); } @@ -184,57 +177,7 @@ class EnterprisePlatformKeysTest done_callback.Run(); } - void SetPolicy() { - // Extensions that are force-installed come from an update URL, which - // defaults to the webstore. Use a mock URL for this test with an update - // manifest that includes the crx file of the test extension. - GURL update_manifest_url( - embedded_test_server()->GetURL(kUpdateManifestPath)); - - std::unique_ptr<base::ListValue> forcelist(new base::ListValue); - forcelist->AppendString(base::StringPrintf( - "%s;%s", kTestExtensionID, update_manifest_url.spec().c_str())); - - policy::PolicyMap policy; - policy.Set(policy::key::kExtensionInstallForcelist, - policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_MACHINE, - policy::POLICY_SOURCE_CLOUD, std::move(forcelist), nullptr); - - // Set the policy and wait until the extension is installed. - TestExtensionRegistryObserver observer(ExtensionRegistry::Get(profile())); - mock_policy_provider()->UpdateChromePolicy(policy); - observer.WaitForExtensionWillBeInstalled(); - } - private: - // Replace "mock.http" with "127.0.0.1:<port>" on "update_manifest.xml" files. - // Host resolver doesn't work here because the test file doesn't know the - // correct port number. - std::unique_ptr<net::test_server::HttpResponse> InterceptMockHttp( - const net::test_server::HttpRequest& request) { - const std::string kFileNameToIntercept = "update_manifest.xml"; - if (request.GetURL().ExtractFileName() != kFileNameToIntercept) - return nullptr; - - base::FilePath test_data_dir; - base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); - // Remove the leading '/'. - std::string relative_manifest_path = request.GetURL().path().substr(1); - std::string manifest_response; - CHECK(base::ReadFileToString(test_data_dir.Append(relative_manifest_path), - &manifest_response)); - - base::ReplaceSubstringsAfterOffset( - &manifest_response, 0, "mock.http", - embedded_test_server()->host_port_pair().ToString()); - - std::unique_ptr<net::test_server::BasicHttpResponse> response( - new net::test_server::BasicHttpResponse()); - response->set_content_type("text/xml"); - response->set_content(manifest_response); - return response; - } - void PrepareTestSystemSlotOnIO( crypto::ScopedTestSystemNSSKeySlot* system_slot) override { // Import a private key to the system slot. The Javascript part of this @@ -263,7 +206,9 @@ IN_PROC_BROWSER_TEST_P(EnterprisePlatformKeysTest, Basic) { loop.QuitClosure())); loop.Run(); } - SetPolicy(); + policy_test_utils::SetExtensionInstallForcelistPolicy( + kTestExtensionID, embedded_test_server()->GetURL(kUpdateManifestPath), + profile(), mock_policy_provider()); // By default, the system token is disabled. std::string system_token_availability = ""; diff --git a/chromium/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc b/chromium/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc index c68aaa5367b..a7dfd046ebb 100644 --- a/chromium/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc +++ b/chromium/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc @@ -4,44 +4,20 @@ #include "chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h" -#include <string> -#include <utility> - #include "base/base64.h" #include "base/bind.h" -#include "base/callback.h" -#include "base/strings/stringprintf.h" #include "base/task/post_task.h" #include "base/values.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chromeos/attestation/attestation_ca_client.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/extensions/chrome_extension_function_details.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/api/enterprise_platform_keys_private.h" #include "chrome/common/pref_names.h" -#include "chromeos/attestation/attestation_flow.h" -#include "chromeos/cryptohome/async_method_caller.h" -#include "chromeos/cryptohome/cryptohome_parameters.h" -#include "chromeos/dbus/constants/attestation_constants.h" -#include "chromeos/dbus/cryptohome/cryptohome_client.h" -#include "chromeos/dbus/dbus_method_call_status.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/settings/cros_settings_names.h" -#include "chromeos/tpm/install_attributes.h" -#include "components/account_id/account_id.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" -#include "components/user_manager/known_user.h" -#include "components/user_manager/user.h" -#include "components/user_manager/user_manager.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "extensions/common/manifest.h" -#include "google_apis/gaia/gaia_auth_util.h" -#include "third_party/cros_system_api/dbus/service_constants.h" namespace { // Prefix for naming machine keys used for SignedPublicKeyAndChallenge when @@ -53,615 +29,68 @@ namespace extensions { namespace api_epkp = api::enterprise_platform_keys_private; -// Base class - -const char EPKPChallengeKeyBase::kChallengeBadBase64Error[] = - "Challenge is not base64 encoded."; -const char EPKPChallengeKeyBase::kDevicePolicyDisabledError[] = - "Remote attestation is not enabled for your device."; -const char EPKPChallengeKeyBase::kExtensionNotWhitelistedError[] = - "The extension does not have permission to call this function."; -const char EPKPChallengeKeyBase::kResponseBadBase64Error[] = - "Response cannot be encoded in base64."; -const char EPKPChallengeKeyBase::kSignChallengeFailedError[] = - "Failed to sign the challenge."; -const char EPKPChallengeKeyBase::kUserNotManaged[] = - "The user account is not enterprise managed."; - -EPKPChallengeKeyBase::PrepareKeyContext::PrepareKeyContext( - chromeos::attestation::AttestationKeyType key_type, - const AccountId& account_id, - const std::string& key_name, - chromeos::attestation::AttestationCertificateProfile certificate_profile, - bool require_user_consent, - const std::string& key_name_for_spkac, - const base::Callback<void(PrepareKeyResult)>& callback) - : key_type(key_type), - account_id(account_id), - key_name(key_name), - certificate_profile(certificate_profile), - require_user_consent(require_user_consent), - key_name_for_spkac(key_name_for_spkac), - callback(callback) {} - -EPKPChallengeKeyBase::PrepareKeyContext::PrepareKeyContext( - const PrepareKeyContext& other) = default; - -EPKPChallengeKeyBase::PrepareKeyContext::~PrepareKeyContext() { -} - -EPKPChallengeKeyBase::EPKPChallengeKeyBase() - : cryptohome_client_(chromeos::CryptohomeClient::Get()), - async_caller_(cryptohome::AsyncMethodCaller::GetInstance()), - install_attributes_(g_browser_process->platform_part() - ->browser_policy_connector_chromeos() - ->GetInstallAttributes()) { - std::unique_ptr<chromeos::attestation::ServerProxy> ca_client( - new chromeos::attestation::AttestationCAClient()); - default_attestation_flow_.reset(new chromeos::attestation::AttestationFlow( - async_caller_, cryptohome_client_, std::move(ca_client))); - attestation_flow_ = default_attestation_flow_.get(); -} - -EPKPChallengeKeyBase::EPKPChallengeKeyBase( - chromeos::CryptohomeClient* cryptohome_client, - cryptohome::AsyncMethodCaller* async_caller, - chromeos::attestation::AttestationFlow* attestation_flow, - chromeos::InstallAttributes* install_attributes) : - cryptohome_client_(cryptohome_client), - async_caller_(async_caller), - attestation_flow_(attestation_flow), - install_attributes_(install_attributes) { -} +EPKPChallengeKey::EPKPChallengeKey() = default; +EPKPChallengeKey::~EPKPChallengeKey() = default; -EPKPChallengeKeyBase::~EPKPChallengeKeyBase() { -} - -void EPKPChallengeKeyBase::GetDeviceAttestationEnabled( - const base::Callback<void(bool)>& callback) const { - chromeos::CrosSettings* settings = chromeos::CrosSettings::Get(); - chromeos::CrosSettingsProvider::TrustedStatus status = - settings->PrepareTrustedValues( - base::Bind(&EPKPChallengeKeyBase::GetDeviceAttestationEnabled, - base::Unretained(this), callback)); - - bool value = false; - switch (status) { - case chromeos::CrosSettingsProvider::TRUSTED: - if (!settings->GetBoolean(chromeos::kDeviceAttestationEnabled, &value)) - value = false; - break; - case chromeos::CrosSettingsProvider::TEMPORARILY_UNTRUSTED: - // Do nothing. This function will be called again when the values are - // ready. - return; - case chromeos::CrosSettingsProvider::PERMANENTLY_UNTRUSTED: - // If the value cannot be trusted, we assume that the device attestation - // is false to be on the safe side. - break; - } - - callback.Run(value); +void EPKPChallengeKey::RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* registry) { + registry->RegisterListPref(prefs::kAttestationExtensionWhitelist); } -bool EPKPChallengeKeyBase::IsEnterpriseDevice() const { - return install_attributes_->IsEnterpriseManaged(); -} +const char EPKPChallengeKey::kExtensionNotWhitelistedError[] = + "The extension does not have permission to call this function."; +const char EPKPChallengeKey::kChallengeBadBase64Error[] = + "Challenge is not base64 encoded."; -bool EPKPChallengeKeyBase::IsExtensionWhitelisted() const { - if (!chromeos::ProfileHelper::Get()->GetUserByProfile(profile_)) { +// Check if the extension is whitelisted in the user policy. +bool EPKPChallengeKey::IsExtensionWhitelisted( + Profile* profile, + scoped_refptr<const Extension> extension) { + if (!chromeos::ProfileHelper::Get()->GetUserByProfile(profile)) { // Only allow remote attestation for apps that were force-installed on the // login/signin screen. // TODO(drcrash): Use a separate device-wide policy for the API. - return Manifest::IsPolicyLocation(extension_->location()); + return Manifest::IsPolicyLocation(extension->location()); } - if (Manifest::IsComponentLocation(extension_->location())) { + if (Manifest::IsComponentLocation(extension->location())) { // Note: For this to even be called, the component extension must also be // whitelisted in chrome/common/extensions/api/_permission_features.json return true; } const base::ListValue* list = - profile_->GetPrefs()->GetList(prefs::kAttestationExtensionWhitelist); - base::Value value(extension_->id()); + profile->GetPrefs()->GetList(prefs::kAttestationExtensionWhitelist); + base::Value value(extension->id()); return list->Find(value) != list->end(); } -AccountId EPKPChallengeKeyBase::GetAccountId() const { - const user_manager::User* user = - chromeos::ProfileHelper::Get()->GetUserByProfile(profile_); - - // Signin profile doesn't have associated user. - if (!user) { - return EmptyAccountId(); - } - - return user->GetAccountId(); -} - -bool EPKPChallengeKeyBase::IsUserAffiliated() const { - const user_manager::User* const user = - user_manager::UserManager::Get()->FindUser(GetAccountId()); - - if (user) { - return user->IsAffiliated(); - } - - return false; -} - -std::string EPKPChallengeKeyBase::GetEnterpriseDomain() const { - return install_attributes_->GetDomain(); -} - -std::string EPKPChallengeKeyBase::GetUserEmail() const { - return GetAccountId().GetUserEmail(); -} - -std::string EPKPChallengeKeyBase::GetDeviceId() const { - return install_attributes_->GetDeviceId(); -} - -void EPKPChallengeKeyBase::PrepareKey( - chromeos::attestation::AttestationKeyType key_type, - const AccountId& account_id, - const std::string& key_name, - chromeos::attestation::AttestationCertificateProfile certificate_profile, - bool require_user_consent, - const std::string& key_name_for_spkac, - const base::Callback<void(PrepareKeyResult)>& callback) { - const PrepareKeyContext context = - PrepareKeyContext(key_type, account_id, key_name, certificate_profile, - require_user_consent, key_name_for_spkac, callback); - cryptohome_client_->TpmAttestationIsPrepared( - base::BindOnce(&EPKPChallengeKeyBase::IsAttestationPreparedCallback, - base::Unretained(this), context)); -} - -void EPKPChallengeKeyBase::IsAttestationPreparedCallback( - const PrepareKeyContext& context, - base::Optional<bool> result) { - if (!result.has_value()) { - context.callback.Run(PREPARE_KEY_DBUS_ERROR); - return; - } - if (!result.value()) { - cryptohome_client_->TpmIsEnabled( - base::BindOnce(&EPKPChallengeKeyBase::PrepareKeyErrorHandlerCallback, - base::Unretained(this), context)); - return; - } - - if (!context.key_name_for_spkac.empty()) { - // Generate a new key and have it signed by PCA. - attestation_flow_->GetCertificate( - context.certificate_profile, context.account_id, - std::string(), // Not used. - true, // Force a new key to be generated. - context.key_name_for_spkac, - base::Bind(&EPKPChallengeKeyBase::GetCertificateCallback, - base::Unretained(this), context.callback)); - return; - } - // Attestation is available, see if the key we need already exists. - cryptohome_client_->TpmAttestationDoesKeyExist( - context.key_type, - cryptohome::CreateAccountIdentifierFromAccountId(context.account_id), - context.key_name, - base::BindOnce(&EPKPChallengeKeyBase::DoesKeyExistCallback, - base::Unretained(this), context)); -} - -void EPKPChallengeKeyBase::PrepareKeyErrorHandlerCallback( - const PrepareKeyContext& context, - base::Optional<bool> is_tpm_enabled) { - if (!is_tpm_enabled.has_value()) { - context.callback.Run(PREPARE_KEY_DBUS_ERROR); - return; - } - - if (is_tpm_enabled.value()) { - context.callback.Run(PREPARE_KEY_RESET_REQUIRED); - } else { - context.callback.Run(PREPARE_KEY_ATTESTATION_UNSUPPORTED); - } -} - -void EPKPChallengeKeyBase::DoesKeyExistCallback( - const PrepareKeyContext& context, - base::Optional<bool> result) { - if (!result.has_value()) { - context.callback.Run(PREPARE_KEY_DBUS_ERROR); - return; - } - - if (result.value()) { - // The key exists. Do nothing more. - context.callback.Run(PREPARE_KEY_OK); - } else { - // The key does not exist. Create a new key and have it signed by PCA. - if (context.require_user_consent) { - // We should ask the user explicitly before sending any private - // information to PCA. - AskForUserConsent( - base::Bind(&EPKPChallengeKeyBase::AskForUserConsentCallback, - base::Unretained(this), context)); - } else { - // User consent is not required. Skip to the next step. - AskForUserConsentCallback(context, true); - } - } -} - -void EPKPChallengeKeyBase::AskForUserConsent( - const base::Callback<void(bool)>& callback) const { - // TODO(davidyu): right now we just simply reject the request before we have - // a way to ask for user consent. - callback.Run(false); -} - -void EPKPChallengeKeyBase::AskForUserConsentCallback( - const PrepareKeyContext& context, - bool result) { - if (!result) { - // The user rejects the request. - context.callback.Run(PREPARE_KEY_USER_REJECTED); - return; - } - - // Generate a new key and have it signed by PCA. - attestation_flow_->GetCertificate( - context.certificate_profile, context.account_id, - std::string(), // Not used. - true, // Force a new key to be generated. - std::string(), // Leave key name empty to generate a default name. - base::Bind(&EPKPChallengeKeyBase::GetCertificateCallback, - base::Unretained(this), context.callback)); -} - -void EPKPChallengeKeyBase::GetCertificateCallback( - const base::Callback<void(PrepareKeyResult)>& callback, - chromeos::attestation::AttestationStatus status, - const std::string& pem_certificate_chain) { - if (status != chromeos::attestation::ATTESTATION_SUCCESS) { - callback.Run(PREPARE_KEY_GET_CERTIFICATE_FAILED); - return; - } - - callback.Run(PREPARE_KEY_OK); -} - -// Implementation of ChallengeMachineKey() - -const char EPKPChallengeMachineKey::kGetCertificateFailedError[] = - "Failed to get Enterprise machine certificate. Error code = %d"; -const char EPKPChallengeMachineKey::kKeyRegistrationFailedError[] = - "Machine key registration failed."; -const char EPKPChallengeMachineKey::kNonEnterpriseDeviceError[] = - "The device is not enterprise enrolled."; - -EPKPChallengeMachineKey::EPKPChallengeMachineKey() : EPKPChallengeKeyBase() { -} - -EPKPChallengeMachineKey::EPKPChallengeMachineKey( - chromeos::CryptohomeClient* cryptohome_client, - cryptohome::AsyncMethodCaller* async_caller, - chromeos::attestation::AttestationFlow* attestation_flow, - chromeos::InstallAttributes* install_attributes) : - EPKPChallengeKeyBase(cryptohome_client, - async_caller, - attestation_flow, - install_attributes) { -} - -EPKPChallengeMachineKey::~EPKPChallengeMachineKey() { -} - -void EPKPChallengeMachineKey::Run(scoped_refptr<ExtensionFunction> caller, - const ChallengeKeyCallback& callback, - const std::string& challenge, - bool register_key) { - callback_ = callback; - profile_ = ChromeExtensionFunctionDetails(caller.get()).GetProfile(); - extension_ = scoped_refptr<const Extension>(caller->extension()); - - // Check if the device is enterprise enrolled. - if (!IsEnterpriseDevice()) { - callback_.Run(false, kNonEnterpriseDeviceError); - return; - } - - // Check if the extension is whitelisted in the user policy. - if (!IsExtensionWhitelisted()) { - callback_.Run(false, kExtensionNotWhitelistedError); - return; - } - - // Check whether the user is managed unless the signin profile is used. - if (chromeos::ProfileHelper::Get()->GetUserByProfile(profile_) && - !IsUserAffiliated()) { - callback_.Run(false, kUserNotManaged); - return; - } - - // Check if RA is enabled in the device policy. - GetDeviceAttestationEnabled( - base::Bind(&EPKPChallengeMachineKey::GetDeviceAttestationEnabledCallback, - base::Unretained(this), challenge, register_key)); -} - -void EPKPChallengeMachineKey::DecodeAndRun( +void EPKPChallengeKey::Run( + chromeos::attestation::AttestationKeyType type, scoped_refptr<ExtensionFunction> caller, - const ChallengeKeyCallback& callback, - const std::string& encoded_challenge, + chromeos::attestation::TpmChallengeKeyCallback callback, + const std::string& challenge, bool register_key) { - std::string challenge; - if (!base::Base64Decode(encoded_challenge, &challenge)) { - callback.Run(false, kChallengeBadBase64Error); - return; - } - Run(caller, callback, challenge, register_key); -} + Profile* profile = ChromeExtensionFunctionDetails(caller.get()).GetProfile(); -void EPKPChallengeMachineKey::GetDeviceAttestationEnabledCallback( - const std::string& challenge, - bool register_key, - bool enabled) { - if (!enabled) { - callback_.Run(false, kDevicePolicyDisabledError); + if (!IsExtensionWhitelisted(profile, caller->extension())) { + std::move(callback).Run( + chromeos::attestation::TpmChallengeKeyResult::MakeError( + kExtensionNotWhitelistedError)); return; } - // The EMK cannot be registered as that would relinquish it and the DMServer - // relies on it to remain stable. If register_key = true, generate a new - // machine key to side-load into the system-wide token. This key will be - // used for SignedPublicKeyAndChallenge but the challenge response will still - // be singed using the stable EMK. std::string key_name_for_spkac; - if (register_key) { - key_name_for_spkac = kEnterpriseMachineKeyForSpkacPrefix + extension_->id(); - } - PrepareKey(chromeos::attestation::KEY_DEVICE, - EmptyAccountId(), // Not used. - chromeos::attestation::kEnterpriseMachineKey, - chromeos::attestation::PROFILE_ENTERPRISE_MACHINE_CERTIFICATE, - false, // user consent is not required. - key_name_for_spkac, - base::Bind(&EPKPChallengeMachineKey::PrepareKeyCallback, - base::Unretained(this), challenge, register_key, - key_name_for_spkac)); -} - -void EPKPChallengeMachineKey::PrepareKeyCallback( - const std::string& challenge, - bool register_key, - const std::string& key_name_for_spkac, - PrepareKeyResult result) { - if (result != PREPARE_KEY_OK) { - callback_.Run(false, - base::StringPrintf(kGetCertificateFailedError, result)); - return; - } - - // Everything is checked. Sign the challenge. - async_caller_->TpmAttestationSignEnterpriseChallenge( - chromeos::attestation::KEY_DEVICE, - cryptohome::Identification(), // Not used. - chromeos::attestation::kEnterpriseMachineKey, GetEnterpriseDomain(), - GetDeviceId(), - register_key ? chromeos::attestation::CHALLENGE_INCLUDE_SIGNED_PUBLIC_KEY - : chromeos::attestation::CHALLENGE_OPTION_NONE, - challenge, key_name_for_spkac, - base::Bind(&EPKPChallengeMachineKey::SignChallengeCallback, - base::Unretained(this), register_key)); -} - -void EPKPChallengeMachineKey::SignChallengeCallback( - bool register_key, - bool success, - const std::string& response) { - if (!success) { - callback_.Run(false, kSignChallengeFailedError); - return; - } - if (register_key) { - std::string key_name_for_spkac = - kEnterpriseMachineKeyForSpkacPrefix + extension_->id(); - async_caller_->TpmAttestationRegisterKey( - chromeos::attestation::KEY_DEVICE, - cryptohome::Identification(), // Not used. - key_name_for_spkac, - base::Bind(&EPKPChallengeMachineKey::RegisterKeyCallback, - base::Unretained(this), response)); - } else { - RegisterKeyCallback(response, true, cryptohome::MOUNT_ERROR_NONE); - } -} - -void EPKPChallengeMachineKey::RegisterKeyCallback( - const std::string& response, - bool success, - cryptohome::MountError return_code) { - if (!success || return_code != cryptohome::MOUNT_ERROR_NONE) { - callback_.Run(false, kKeyRegistrationFailedError); - return; - } - callback_.Run(true, response); -} - -// Implementation of ChallengeUserKey() - -const char EPKPChallengeUserKey::kGetCertificateFailedError[] = - "Failed to get Enterprise user certificate. Error code = %d"; -const char EPKPChallengeUserKey::kKeyRegistrationFailedError[] = - "Key registration failed."; -const char EPKPChallengeUserKey::kUserPolicyDisabledError[] = - "Remote attestation is not enabled for your account."; -const char EPKPChallengeUserKey::kUserKeyNotAvailable[] = - "User keys cannot be challenged in this profile."; - -EPKPChallengeUserKey::EPKPChallengeUserKey() : EPKPChallengeKeyBase() { -} - -EPKPChallengeUserKey::EPKPChallengeUserKey( - chromeos::CryptohomeClient* cryptohome_client, - cryptohome::AsyncMethodCaller* async_caller, - chromeos::attestation::AttestationFlow* attestation_flow, - chromeos::InstallAttributes* install_attributes) : - EPKPChallengeKeyBase(cryptohome_client, - async_caller, - attestation_flow, - install_attributes) { -} - -EPKPChallengeUserKey::~EPKPChallengeUserKey() { -} - -void EPKPChallengeUserKey::RegisterProfilePrefs( - user_prefs::PrefRegistrySyncable* registry) { - registry->RegisterBooleanPref(prefs::kAttestationEnabled, false); - registry->RegisterListPref(prefs::kAttestationExtensionWhitelist); -} - -void EPKPChallengeUserKey::Run(scoped_refptr<ExtensionFunction> caller, - const ChallengeKeyCallback& callback, - const std::string& challenge, - bool register_key) { - callback_ = callback; - profile_ = ChromeExtensionFunctionDetails(caller.get()).GetProfile(); - extension_ = scoped_refptr<const Extension>(caller->extension()); - - // Check if user keys are available in this profile. - if (!chromeos::ProfileHelper::Get()->GetUserByProfile(profile_)) { - callback_.Run(false, EPKPChallengeUserKey::kUserKeyNotAvailable); - return; - } - - // Check if RA is enabled in the user policy. - if (!IsRemoteAttestationEnabledForUser()) { - callback_.Run(false, kUserPolicyDisabledError); - return; - } - - // Check if the extension is whitelisted in the user policy. - if (!IsExtensionWhitelisted()) { - callback_.Run(false, kExtensionNotWhitelistedError); - return; - } - - if (IsEnterpriseDevice()) { - if (!IsUserAffiliated()) { - callback_.Run(false, kUserNotManaged); - return; - } - - // Check if RA is enabled in the device policy. - GetDeviceAttestationEnabled( - base::Bind(&EPKPChallengeUserKey::GetDeviceAttestationEnabledCallback, - base::Unretained(this), challenge, register_key, - false)); // user consent is not required. - } else { - // For personal devices, we don't need to check if RA is enabled in the - // device, but we need to ask for user consent if the key does not exist. - GetDeviceAttestationEnabledCallback(challenge, register_key, - true, // user consent is required. - true); // attestation is enabled. - } -} - -void EPKPChallengeUserKey::DecodeAndRun(scoped_refptr<ExtensionFunction> caller, - const ChallengeKeyCallback& callback, - const std::string& encoded_challenge, - bool register_key) { - std::string challenge; - if (!base::Base64Decode(encoded_challenge, &challenge)) { - callback.Run(false, kChallengeBadBase64Error); - return; - } - Run(caller, callback, challenge, register_key); -} - -void EPKPChallengeUserKey::GetDeviceAttestationEnabledCallback( - const std::string& challenge, - bool register_key, - bool require_user_consent, - bool enabled) { - if (!enabled) { - callback_.Run(false, kDevicePolicyDisabledError); - return; - } - - PrepareKey(chromeos::attestation::KEY_USER, GetAccountId(), - chromeos::attestation::kEnterpriseUserKey, - chromeos::attestation::PROFILE_ENTERPRISE_USER_CERTIFICATE, - require_user_consent, std::string() /* key_name_for_spkac */, - base::Bind(&EPKPChallengeUserKey::PrepareKeyCallback, - base::Unretained(this), challenge, register_key)); -} - -void EPKPChallengeUserKey::PrepareKeyCallback(const std::string& challenge, - bool register_key, - PrepareKeyResult result) { - if (result != PREPARE_KEY_OK) { - callback_.Run(false, - base::StringPrintf(kGetCertificateFailedError, result)); - return; - } - - // Everything is checked. Sign the challenge. - async_caller_->TpmAttestationSignEnterpriseChallenge( - chromeos::attestation::KEY_USER, - cryptohome::Identification(GetAccountId()), - chromeos::attestation::kEnterpriseUserKey, GetUserEmail(), GetDeviceId(), - register_key ? chromeos::attestation::CHALLENGE_INCLUDE_SIGNED_PUBLIC_KEY - : chromeos::attestation::CHALLENGE_OPTION_NONE, - challenge, std::string() /* key_name_for_spkac */, - base::Bind(&EPKPChallengeUserKey::SignChallengeCallback, - base::Unretained(this), register_key)); -} - -void EPKPChallengeUserKey::SignChallengeCallback(bool register_key, - bool success, - const std::string& response) { - if (!success) { - callback_.Run(false, kSignChallengeFailedError); - return; - } - - if (register_key) { - async_caller_->TpmAttestationRegisterKey( - chromeos::attestation::KEY_USER, - cryptohome::Identification(GetAccountId()), - chromeos::attestation::kEnterpriseUserKey, - base::Bind(&EPKPChallengeUserKey::RegisterKeyCallback, - base::Unretained(this), response)); - } else { - RegisterKeyCallback(response, true, cryptohome::MOUNT_ERROR_NONE); + if (register_key && (type == chromeos::attestation::KEY_DEVICE)) { + key_name_for_spkac = + kEnterpriseMachineKeyForSpkacPrefix + caller->extension()->id(); } -} - -void EPKPChallengeUserKey::RegisterKeyCallback( - const std::string& response, - bool success, - cryptohome::MountError return_code) { - if (!success || return_code != cryptohome::MOUNT_ERROR_NONE) { - callback_.Run(false, kKeyRegistrationFailedError); - return; - } - callback_.Run(true, response); -} -bool EPKPChallengeUserKey::IsRemoteAttestationEnabledForUser() const { - return profile_->GetPrefs()->GetBoolean(prefs::kAttestationEnabled); + impl_ = chromeos::attestation::TpmChallengeKeyFactory::Create(); + impl_->Run(type, profile, std::move(callback), challenge, register_key, + key_name_for_spkac); } EnterprisePlatformKeysPrivateChallengeMachineKeyFunction:: - EnterprisePlatformKeysPrivateChallengeMachineKeyFunction() - : default_impl_(new EPKPChallengeMachineKey), impl_(default_impl_.get()) {} - -EnterprisePlatformKeysPrivateChallengeMachineKeyFunction:: - EnterprisePlatformKeysPrivateChallengeMachineKeyFunction( - EPKPChallengeMachineKey* impl_for_testing) - : impl_(impl_for_testing) {} + EnterprisePlatformKeysPrivateChallengeMachineKeyFunction() = default; EnterprisePlatformKeysPrivateChallengeMachineKeyFunction:: ~EnterprisePlatformKeysPrivateChallengeMachineKeyFunction() = default; @@ -671,41 +100,41 @@ EnterprisePlatformKeysPrivateChallengeMachineKeyFunction::Run() { std::unique_ptr<api_epkp::ChallengeMachineKey::Params> params( api_epkp::ChallengeMachineKey::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params); - ChallengeKeyCallback callback = + chromeos::attestation::TpmChallengeKeyCallback callback = base::Bind(&EnterprisePlatformKeysPrivateChallengeMachineKeyFunction:: OnChallengedKey, this); + + std::string challenge; + if (!base::Base64Decode(params->challenge, &challenge)) { + return RespondNow(Error(EPKPChallengeKey::kChallengeBadBase64Error)); + } + // base::Unretained is safe on impl_ since its life-cycle matches |this| and // |callback| holds a reference to |this|. - base::Closure task = base::Bind(&EPKPChallengeMachineKey::DecodeAndRun, - base::Unretained(impl_), - scoped_refptr<ExtensionFunction>(this), - callback, params->challenge, false); - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, task); + base::OnceClosure task = base::BindOnce( + &EPKPChallengeKey::Run, base::Unretained(&impl_), + chromeos::attestation::KEY_DEVICE, scoped_refptr<ExtensionFunction>(this), + std::move(callback), challenge, + /*register_key=*/false); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, std::move(task)); return RespondLater(); } void EnterprisePlatformKeysPrivateChallengeMachineKeyFunction::OnChallengedKey( - bool success, - const std::string& data) { - if (success) { + const chromeos::attestation::TpmChallengeKeyResult& result) { + if (result.is_success) { std::string encoded_response; - base::Base64Encode(data, &encoded_response); + base::Base64Encode(result.data, &encoded_response); Respond(ArgumentList( api_epkp::ChallengeMachineKey::Results::Create(encoded_response))); } else { - Respond(Error(data)); + Respond(Error(result.error_message)); } } EnterprisePlatformKeysPrivateChallengeUserKeyFunction:: - EnterprisePlatformKeysPrivateChallengeUserKeyFunction() - : default_impl_(new EPKPChallengeUserKey), impl_(default_impl_.get()) {} - -EnterprisePlatformKeysPrivateChallengeUserKeyFunction:: - EnterprisePlatformKeysPrivateChallengeUserKeyFunction( - EPKPChallengeUserKey* impl_for_testing) - : impl_(impl_for_testing) {} + EnterprisePlatformKeysPrivateChallengeUserKeyFunction() = default; EnterprisePlatformKeysPrivateChallengeUserKeyFunction:: ~EnterprisePlatformKeysPrivateChallengeUserKeyFunction() = default; @@ -715,29 +144,34 @@ EnterprisePlatformKeysPrivateChallengeUserKeyFunction::Run() { std::unique_ptr<api_epkp::ChallengeUserKey::Params> params( api_epkp::ChallengeUserKey::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params); - ChallengeKeyCallback callback = base::Bind( + chromeos::attestation::TpmChallengeKeyCallback callback = base::Bind( &EnterprisePlatformKeysPrivateChallengeUserKeyFunction::OnChallengedKey, this); + + std::string challenge; + if (!base::Base64Decode(params->challenge, &challenge)) { + return RespondNow(Error(EPKPChallengeKey::kChallengeBadBase64Error)); + } + // base::Unretained is safe on impl_ since its life-cycle matches |this| and // |callback| holds a reference to |this|. - base::Closure task = - base::Bind(&EPKPChallengeUserKey::DecodeAndRun, base::Unretained(impl_), - scoped_refptr<ExtensionFunction>(this), callback, - params->challenge, params->register_key); - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, task); + base::OnceClosure task = base::BindOnce( + &EPKPChallengeKey::Run, base::Unretained(&impl_), + chromeos::attestation::KEY_USER, scoped_refptr<ExtensionFunction>(this), + std::move(callback), challenge, params->register_key); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, std::move(task)); return RespondLater(); } void EnterprisePlatformKeysPrivateChallengeUserKeyFunction::OnChallengedKey( - bool success, - const std::string& data) { - if (success) { + const chromeos::attestation::TpmChallengeKeyResult& result) { + if (result.is_success) { std::string encoded_response; - base::Base64Encode(data, &encoded_response); + base::Base64Encode(result.data, &encoded_response); Respond(ArgumentList( api_epkp::ChallengeUserKey::Results::Create(encoded_response))); } else { - Respond(Error(data)); + Respond(Error(result.error_message)); } } diff --git a/chromium/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h b/chromium/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h index e8e9fa09d43..82231173f06 100644 --- a/chromium/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h +++ b/chromium/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h @@ -11,272 +11,60 @@ #include <memory> #include <string> -#include "base/callback.h" -#include "base/compiler_specific.h" -#include "base/optional.h" -#include "chrome/common/extensions/api/enterprise_platform_keys_private.h" -#include "chromeos/attestation/attestation_flow.h" +#include "chrome/browser/chromeos/attestation/tpm_challenge_key.h" #include "chromeos/dbus/constants/attestation_constants.h" -#include "chromeos/dbus/cryptohome/cryptohome_client.h" -#include "components/account_id/account_id.h" #include "extensions/browser/extension_function.h" #include "extensions/common/extension.h" -#include "third_party/cros_system_api/dbus/service_constants.h" class Profile; -namespace chromeos { -class CryptohomeClient; -class InstallAttributes; -} - -namespace cryptohome { -class AsyncMethodCaller; -} - namespace user_prefs { class PrefRegistrySyncable; } namespace extensions { -// A callback for challenge key operations. If the operation succeeded, -// |success| is true and |data| is the challenge response. Otherwise, |success| -// is false and |data| is an error message. -using ChallengeKeyCallback = - base::Callback<void(bool success, const std::string& data)>; - -class EPKPChallengeKeyBase { +class EPKPChallengeKey { public: - static const char kChallengeBadBase64Error[]; - static const char kDevicePolicyDisabledError[]; static const char kExtensionNotWhitelistedError[]; - static const char kResponseBadBase64Error[]; - static const char kSignChallengeFailedError[]; - static const char kUserNotManaged[]; - - protected: - enum PrepareKeyResult { - PREPARE_KEY_OK = 0, - PREPARE_KEY_DBUS_ERROR, - PREPARE_KEY_USER_REJECTED, - PREPARE_KEY_GET_CERTIFICATE_FAILED, - PREPARE_KEY_RESET_REQUIRED, - PREPARE_KEY_ATTESTATION_UNSUPPORTED - }; - - EPKPChallengeKeyBase(); - EPKPChallengeKeyBase( - chromeos::CryptohomeClient* cryptohome_client, - cryptohome::AsyncMethodCaller* async_caller, - chromeos::attestation::AttestationFlow* attestation_flow, - chromeos::InstallAttributes* install_attributes); - virtual ~EPKPChallengeKeyBase(); - - // Returns a trusted value from CroSettings indicating if the device - // attestation is enabled. - void GetDeviceAttestationEnabled( - const base::Callback<void(bool)>& callback) const; - - // Returns true if the device is enterprise managed. - bool IsEnterpriseDevice() const; - - // Returns true if the extension is white-listed in the user policy. - bool IsExtensionWhitelisted() const; - - // Returns true if the user is managed and is affiliated with the domain the - // device is enrolled to. - bool IsUserAffiliated() const; - - // Returns the enterprise domain the device is enrolled to. - std::string GetEnterpriseDomain() const; - - // Returns the user email. - std::string GetUserEmail() const; - - // Returns account id. - AccountId GetAccountId() const; - - // Returns the enterprise virtual device ID. - std::string GetDeviceId() const; - - // Prepares the key for signing. It will first check if a new key should be - // generated, i.e. |key_name_for_spkac| is not empty or the key doesn't - // exist and, if necessary, call AttestationFlow::GetCertificate() to get a - // new one. If require_user_consent is true, it will explicitly ask for user - // consent before calling GetCertificate(). - void PrepareKey( - chromeos::attestation::AttestationKeyType key_type, - const AccountId& account_id, - const std::string& key_name, - chromeos::attestation::AttestationCertificateProfile certificate_profile, - bool require_user_consent, - const std::string& key_name_for_spkac, - const base::Callback<void(PrepareKeyResult)>& callback); - - chromeos::CryptohomeClient* cryptohome_client_; - cryptohome::AsyncMethodCaller* async_caller_; - chromeos::attestation::AttestationFlow* attestation_flow_; - std::unique_ptr<chromeos::attestation::AttestationFlow> - default_attestation_flow_; - ChallengeKeyCallback callback_; - Profile* profile_; - scoped_refptr<const Extension> extension_; - - private: - // Holds the context of a PrepareKey() operation. - struct PrepareKeyContext { - PrepareKeyContext(chromeos::attestation::AttestationKeyType key_type, - const AccountId& account_id, - const std::string& key_name, - chromeos::attestation::AttestationCertificateProfile - certificate_profile, - bool require_user_consent, - const std::string& key_name_for_spkac, - const base::Callback<void(PrepareKeyResult)>& callback); - PrepareKeyContext(const PrepareKeyContext& other); - ~PrepareKeyContext(); - - chromeos::attestation::AttestationKeyType key_type; - const AccountId account_id; - const std::string key_name; - chromeos::attestation::AttestationCertificateProfile certificate_profile; - bool require_user_consent; - std::string key_name_for_spkac; - const base::Callback<void(PrepareKeyResult)> callback; - }; - - void IsAttestationPreparedCallback(const PrepareKeyContext& context, - base::Optional<bool> result); - void PrepareKeyErrorHandlerCallback(const PrepareKeyContext& context, - base::Optional<bool> is_tpm_enabled); - void DoesKeyExistCallback(const PrepareKeyContext& context, - base::Optional<bool> result); - void AskForUserConsent(const base::Callback<void(bool)>& callback) const; - void AskForUserConsentCallback( - const PrepareKeyContext& context, - bool result); - void GetCertificateCallback( - const base::Callback<void(PrepareKeyResult)>& callback, - chromeos::attestation::AttestationStatus status, - const std::string& pem_certificate_chain); - - chromeos::InstallAttributes* install_attributes_; -}; - -class EPKPChallengeMachineKey : public EPKPChallengeKeyBase { - public: - static const char kGetCertificateFailedError[]; - static const char kKeyRegistrationFailedError[]; - static const char kNonEnterpriseDeviceError[]; - - EPKPChallengeMachineKey(); - EPKPChallengeMachineKey( - chromeos::CryptohomeClient* cryptohome_client, - cryptohome::AsyncMethodCaller* async_caller, - chromeos::attestation::AttestationFlow* attestation_flow, - chromeos::InstallAttributes* install_attributes); - ~EPKPChallengeMachineKey() override; - - // Asynchronously run the flow to challenge a machine key in the |caller| - // context. - void Run(scoped_refptr<ExtensionFunction> caller, - const ChallengeKeyCallback& callback, - const std::string& encoded_challenge, - bool register_key); - - // Like |Run| but expects a Base64 |encoded_challenge|. - void DecodeAndRun(scoped_refptr<ExtensionFunction> caller, - const ChallengeKeyCallback& callback, - const std::string& encoded_challenge, - bool register_key); - - private: - static const char kKeyName[]; - - void GetDeviceAttestationEnabledCallback(const std::string& challenge, - bool register_key, - bool enabled); - void PrepareKeyCallback(const std::string& challenge, - bool register_key, - const std::string& key_name_for_spkac, - PrepareKeyResult result); - void SignChallengeCallback(bool register_key, - bool success, - const std::string& response); - void RegisterKeyCallback(const std::string& response, - bool success, - cryptohome::MountError return_code); -}; - -class EPKPChallengeUserKey : public EPKPChallengeKeyBase { - public: - static const char kGetCertificateFailedError[]; - static const char kKeyRegistrationFailedError[]; - static const char kUserKeyNotAvailable[]; - static const char kUserPolicyDisabledError[]; - - EPKPChallengeUserKey(); - EPKPChallengeUserKey( - chromeos::CryptohomeClient* cryptohome_client, - cryptohome::AsyncMethodCaller* async_caller, - chromeos::attestation::AttestationFlow* attestation_flow, - chromeos::InstallAttributes* install_attributes); - ~EPKPChallengeUserKey() override; + static const char kChallengeBadBase64Error[]; + EPKPChallengeKey(); + EPKPChallengeKey(const EPKPChallengeKey&) = delete; + EPKPChallengeKey& operator=(const EPKPChallengeKey&) = delete; + ~EPKPChallengeKey(); static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); - // Asynchronously run the flow to challenge a user key in the |caller| + // Asynchronously run the flow to challenge a key in the |caller| // context. - void Run(scoped_refptr<ExtensionFunction> caller, - const ChallengeKeyCallback& callback, + void Run(chromeos::attestation::AttestationKeyType type, + scoped_refptr<ExtensionFunction> caller, + chromeos::attestation::TpmChallengeKeyCallback callback, const std::string& challenge, bool register_key); - // Like |Run| but expects a Base64 |encoded_challenge|. - void DecodeAndRun(scoped_refptr<ExtensionFunction> caller, - const ChallengeKeyCallback& callback, - const std::string& encoded_challenge, - bool register_key); - private: - static const char kKeyName[]; - - void GetDeviceAttestationEnabledCallback(const std::string& challenge, - bool register_key, - bool require_user_consent, - bool enabled); - void PrepareKeyCallback(const std::string& challenge, - bool register_key, - PrepareKeyResult result); - void SignChallengeCallback(bool register_key, - bool success, - const std::string& response); - void RegisterKeyCallback(const std::string& response, - bool success, - cryptohome::MountError return_code); + // Check if the extension is whitelisted in the user policy. + bool IsExtensionWhitelisted(Profile* profile, + scoped_refptr<const Extension> extension); - bool IsRemoteAttestationEnabledForUser() const; + std::unique_ptr<chromeos::attestation::TpmChallengeKey> impl_; }; class EnterprisePlatformKeysPrivateChallengeMachineKeyFunction : public ExtensionFunction { public: EnterprisePlatformKeysPrivateChallengeMachineKeyFunction(); - explicit EnterprisePlatformKeysPrivateChallengeMachineKeyFunction( - EPKPChallengeMachineKey* impl_for_testing); private: ~EnterprisePlatformKeysPrivateChallengeMachineKeyFunction() override; ResponseAction Run() override; - // Called when the challenge operation is complete. If the operation succeeded - // |success| will be true and |data| will contain the challenge response data. - // Otherwise |success| will be false and |data| is an error message. - void OnChallengedKey(bool success, const std::string& data); + // Called when the challenge operation is complete. + void OnChallengedKey( + const chromeos::attestation::TpmChallengeKeyResult& result); - std::unique_ptr<EPKPChallengeMachineKey> default_impl_; - EPKPChallengeMachineKey* impl_; + EPKPChallengeKey impl_; DECLARE_EXTENSION_FUNCTION( "enterprise.platformKeysPrivate.challengeMachineKey", @@ -287,20 +75,16 @@ class EnterprisePlatformKeysPrivateChallengeUserKeyFunction : public ExtensionFunction { public: EnterprisePlatformKeysPrivateChallengeUserKeyFunction(); - explicit EnterprisePlatformKeysPrivateChallengeUserKeyFunction( - EPKPChallengeUserKey* impl_for_testing); private: ~EnterprisePlatformKeysPrivateChallengeUserKeyFunction() override; ResponseAction Run() override; - // Called when the challenge operation is complete. If the operation succeeded - // |success| will be true and |data| will contain the challenge response data. - // Otherwise |success| will be false and |data| is an error message. - void OnChallengedKey(bool success, const std::string& data); + // Called when the challenge operation is complete. + void OnChallengedKey( + const chromeos::attestation::TpmChallengeKeyResult& result); - std::unique_ptr<EPKPChallengeUserKey> default_impl_; - EPKPChallengeUserKey* impl_; + EPKPChallengeKey impl_; DECLARE_EXTENSION_FUNCTION("enterprise.platformKeysPrivate.challengeUserKey", ENTERPRISE_PLATFORMKEYSPRIVATE_CHALLENGEUSERKEY) diff --git a/chromium/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc b/chromium/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc index 6230610cb4a..db219faef44 100644 --- a/chromium/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc +++ b/chromium/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc @@ -4,206 +4,59 @@ #include "chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h" -#include <string> +#include <utility> -#include "base/bind.h" -#include "base/location.h" -#include "base/memory/ptr_util.h" -#include "base/strings/stringprintf.h" -#include "base/threading/thread_task_runner_handle.h" #include "base/values.h" +#include "chrome/browser/chromeos/attestation/mock_tpm_challenge_key.h" #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/chromeos/settings/cros_settings.h" -#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h" #include "chrome/browser/extensions/extension_function_test_utils.h" #include "chrome/browser/signin/identity_manager_factory.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/common/chrome_constants.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/browser_with_test_window_test.h" -#include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile_manager.h" -#include "chromeos/attestation/mock_attestation_flow.h" -#include "chromeos/cryptohome/async_method_caller.h" -#include "chromeos/cryptohome/cryptohome_parameters.h" -#include "chromeos/cryptohome/mock_async_method_caller.h" -#include "chromeos/dbus/constants/attestation_constants.h" -#include "chromeos/dbus/cryptohome/fake_cryptohome_client.h" -#include "chromeos/tpm/stub_install_attributes.h" -#include "components/account_id/account_id.h" -#include "components/policy/core/common/cloud/cloud_policy_constants.h" -#include "components/prefs/pref_service.h" #include "components/signin/public/identity_manager/identity_manager.h" #include "components/signin/public/identity_manager/identity_test_utils.h" #include "components/user_manager/scoped_user_manager.h" #include "extensions/common/extension_builder.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/cros_system_api/dbus/service_constants.h" -using testing::_; -using testing::Invoke; using testing::NiceMock; -using testing::Return; -using testing::WithArgs; namespace utils = extension_function_test_utils; namespace extensions { namespace { -// Certificate errors as reported to the calling extension. -const int kDBusError = 1; -const int kUserRejected = 2; -const int kGetCertificateFailed = 3; -const int kResetRequired = 4; -const int kPrepareKeyAttestationUnsupported = 5; - const char kUserEmail[] = "test@google.com"; -void RegisterKeyCallbackTrue( - chromeos::attestation::AttestationKeyType key_type, - const cryptohome::Identification& user_id, - const std::string& key_name, - const cryptohome::AsyncMethodCaller::Callback& callback) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(callback, true, cryptohome::MOUNT_ERROR_NONE)); -} - -void RegisterKeyCallbackFalse( - chromeos::attestation::AttestationKeyType key_type, - const cryptohome::Identification& user_id, - const std::string& key_name, - const cryptohome::AsyncMethodCaller::Callback& callback) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(callback, false, cryptohome::MOUNT_ERROR_NONE)); -} - -void SignChallengeCallbackTrue( - chromeos::attestation::AttestationKeyType key_type, - const cryptohome::Identification& user_id, - const std::string& key_name, - const std::string& domain, - const std::string& device_id, - chromeos::attestation::AttestationChallengeOptions options, - const std::string& challenge, - const std::string& key_name_for_spkac, - const cryptohome::AsyncMethodCaller::DataCallback& callback) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(callback, true, "response")); -} - -void SignChallengeCallbackFalse( - chromeos::attestation::AttestationKeyType key_type, - const cryptohome::Identification& user_id, - const std::string& key_name, - const std::string& domain, - const std::string& device_id, - chromeos::attestation::AttestationChallengeOptions options, - const std::string& challenge, - const std::string& key_name_for_spkac, - const cryptohome::AsyncMethodCaller::DataCallback& callback) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(callback, false, "")); -} - -void GetCertificateCallbackTrue( - chromeos::attestation::AttestationCertificateProfile certificate_profile, - const AccountId& account_id, - const std::string& request_origin, - bool force_new_key, - const std::string& key_name, - const chromeos::attestation::AttestationFlow::CertificateCallback& - callback) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindRepeating(callback, chromeos::attestation::ATTESTATION_SUCCESS, - "certificate")); -} - -void GetCertificateCallbackUnspecifiedFailure( - chromeos::attestation::AttestationCertificateProfile certificate_profile, - const AccountId& account_id, - const std::string& request_origin, - bool force_new_key, - const std::string& key_name, - const chromeos::attestation::AttestationFlow::CertificateCallback& - callback) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindRepeating( - callback, chromeos::attestation::ATTESTATION_UNSPECIFIED_FAILURE, - "")); -} - -void GetCertificateCallbackBadRequestFailure( - chromeos::attestation::AttestationCertificateProfile certificate_profile, - const AccountId& account_id, - const std::string& request_origin, - bool force_new_key, - const std::string& key_name, - const chromeos::attestation::AttestationFlow::CertificateCallback& - callback) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindRepeating( - callback, - chromeos::attestation::ATTESTATION_SERVER_BAD_REQUEST_FAILURE, "")); -} - class EPKPChallengeKeyTestBase : public BrowserWithTestWindowTest { - public: - enum class ProfileType { USER_PROFILE, SIGNIN_PROFILE }; - protected: - explicit EPKPChallengeKeyTestBase(ProfileType profile_type) - : settings_helper_(false), - profile_type_(profile_type), - fake_user_manager_(new chromeos::FakeChromeUserManager), + EPKPChallengeKeyTestBase() + : fake_user_manager_(new chromeos::FakeChromeUserManager()), user_manager_enabler_(base::WrapUnique(fake_user_manager_)) { - // Create the extension. - extension_ = CreateExtension(); - - // Set up the default behavior of mocks. - ON_CALL(mock_async_method_caller_, TpmAttestationRegisterKey(_, _, _, _)) - .WillByDefault(Invoke(RegisterKeyCallbackTrue)); - ON_CALL(mock_async_method_caller_, - TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _, _)) - .WillByDefault(Invoke(SignChallengeCallbackTrue)); - ON_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _)) - .WillByDefault(Invoke(GetCertificateCallbackTrue)); - - stub_install_attributes_.SetCloudManaged("google.com", "device_id"); - - settings_helper_.ReplaceDeviceSettingsProviderWithStub(); - settings_helper_.SetBoolean(chromeos::kDeviceAttestationEnabled, true); + extension_ = ExtensionBuilder("Test").Build(); } void SetUp() override { BrowserWithTestWindowTest::SetUp(); - if (profile_type_ == ProfileType::USER_PROFILE) { - // Set the user preferences. - prefs_ = browser()->profile()->GetPrefs(); - base::ListValue whitelist; - whitelist.AppendString(extension_->id()); - prefs_->Set(prefs::kAttestationExtensionWhitelist, whitelist); - - SetAuthenticatedUser(); - } + prefs_ = browser()->profile()->GetPrefs(); + SetAuthenticatedUser(); + } + + void SetMockTpmChallenger() { + auto mock_tpm_challenge_key = std::make_unique< + NiceMock<chromeos::attestation::MockTpmChallengeKey>>(); + mock_tpm_challenge_key->EnableFake(); + chromeos::attestation::TpmChallengeKeyFactory::SetForTesting( + std::move(mock_tpm_challenge_key)); } // This will be called by BrowserWithTestWindowTest::SetUp(); TestingProfile* CreateProfile() override { - switch (profile_type_) { - case ProfileType::USER_PROFILE: - fake_user_manager_->AddUserWithAffiliation( - AccountId::FromUserEmail(kUserEmail), true); - return profile_manager()->CreateTestingProfile(kUserEmail); - - case ProfileType::SIGNIN_PROFILE: - return profile_manager()->CreateTestingProfile(chrome::kInitialProfile); - } + fake_user_manager_->AddUserWithAffiliation( + AccountId::FromUserEmail(kUserEmail), true); + return profile_manager()->CreateTestingProfile(kUserEmail); } // Derived classes can override this method to set the required authenticated @@ -214,432 +67,90 @@ class EPKPChallengeKeyTestBase : public BrowserWithTestWindowTest { signin::MakePrimaryAccountAvailable(identity_manager, kUserEmail); } - chromeos::FakeCryptohomeClient cryptohome_client_; - NiceMock<cryptohome::MockAsyncMethodCaller> mock_async_method_caller_; - NiceMock<chromeos::attestation::MockAttestationFlow> mock_attestation_flow_; - chromeos::ScopedCrosSettingsTestHelper settings_helper_; scoped_refptr<const Extension> extension_; - chromeos::StubInstallAttributes stub_install_attributes_; - ProfileType profile_type_; // fake_user_manager_ is owned by user_manager_enabler_. - chromeos::FakeChromeUserManager* fake_user_manager_; + chromeos::FakeChromeUserManager* fake_user_manager_ = nullptr; user_manager::ScopedUserManager user_manager_enabler_; PrefService* prefs_ = nullptr; - - private: - scoped_refptr<const Extension> CreateExtension() { - switch (profile_type_) { - case ProfileType::USER_PROFILE: - return ExtensionBuilder("Test").Build(); - - case ProfileType::SIGNIN_PROFILE: - return ExtensionBuilder("Test", ExtensionBuilder::Type::PLATFORM_APP) - .SetLocation(Manifest::Location::EXTERNAL_POLICY) - .Build(); - } - } }; class EPKPChallengeMachineKeyTest : public EPKPChallengeKeyTestBase { protected: - static const char kArgs[]; - - explicit EPKPChallengeMachineKeyTest( - ProfileType profile_type = ProfileType::USER_PROFILE) - : EPKPChallengeKeyTestBase(profile_type), - impl_(&cryptohome_client_, - &mock_async_method_caller_, - &mock_attestation_flow_, - &stub_install_attributes_), - func_(new EnterprisePlatformKeysPrivateChallengeMachineKeyFunction( - &impl_)) { - func_->set_extension(extension_.get()); - } + static const char kFuncArgs[]; - // Returns an error string for the given code. - std::string GetCertificateError(int error_code) { - return base::StringPrintf( - EPKPChallengeMachineKey::kGetCertificateFailedError, - error_code); + EPKPChallengeMachineKeyTest() + : func_(new EnterprisePlatformKeysPrivateChallengeMachineKeyFunction()) { + func_->set_extension(extension_.get()); } - EPKPChallengeMachineKey impl_; scoped_refptr<EnterprisePlatformKeysPrivateChallengeMachineKeyFunction> func_; }; // Base 64 encoding of 'challenge'. -const char EPKPChallengeMachineKeyTest::kArgs[] = "[\"Y2hhbGxlbmdl\"]"; - -TEST_F(EPKPChallengeMachineKeyTest, ChallengeBadBase64) { - EXPECT_EQ(EPKPChallengeKeyBase::kChallengeBadBase64Error, - utils::RunFunctionAndReturnError( - func_.get(), "[\"****\"]", browser())); -} - -TEST_F(EPKPChallengeMachineKeyTest, NonEnterpriseDevice) { - stub_install_attributes_.SetConsumerOwned(); - - EXPECT_EQ(EPKPChallengeMachineKey::kNonEnterpriseDeviceError, - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} +const char EPKPChallengeMachineKeyTest::kFuncArgs[] = "[\"Y2hhbGxlbmdl\"]"; TEST_F(EPKPChallengeMachineKeyTest, ExtensionNotWhitelisted) { base::ListValue empty_whitelist; prefs_->Set(prefs::kAttestationExtensionWhitelist, empty_whitelist); - EXPECT_EQ(EPKPChallengeKeyBase::kExtensionNotWhitelistedError, - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - -TEST_F(EPKPChallengeMachineKeyTest, DevicePolicyDisabled) { - settings_helper_.SetBoolean(chromeos::kDeviceAttestationEnabled, false); - - EXPECT_EQ(EPKPChallengeKeyBase::kDevicePolicyDisabledError, - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); + EXPECT_EQ( + EPKPChallengeKey::kExtensionNotWhitelistedError, + utils::RunFunctionAndReturnError(func_.get(), kFuncArgs, browser())); } -TEST_F(EPKPChallengeMachineKeyTest, DoesKeyExistDbusFailed) { - cryptohome_client_.set_tpm_attestation_does_key_exist_should_succeed(false); - - EXPECT_EQ(GetCertificateError(kDBusError), - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} +TEST_F(EPKPChallengeMachineKeyTest, Success) { + SetMockTpmChallenger(); -TEST_F(EPKPChallengeMachineKeyTest, GetCertificateFailed) { - EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _)) - .WillRepeatedly(Invoke(GetCertificateCallbackUnspecifiedFailure)); - - EXPECT_EQ(GetCertificateError(kGetCertificateFailed), - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - -TEST_F(EPKPChallengeMachineKeyTest, SignChallengeFailed) { - EXPECT_CALL(mock_async_method_caller_, - TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _, _)) - .WillRepeatedly(Invoke(SignChallengeCallbackFalse)); - - EXPECT_EQ(EPKPChallengeKeyBase::kSignChallengeFailedError, - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - -TEST_F(EPKPChallengeMachineKeyTest, KeyExists) { - cryptohome_client_.SetTpmAttestationDeviceCertificate("attest-ent-machine", - std::string()); - // GetCertificate must not be called if the key exists. - EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _)) - .Times(0); - - EXPECT_TRUE(utils::RunFunction(func_.get(), kArgs, browser(), - extensions::api_test_utils::NONE)); -} - -TEST_F(EPKPChallengeMachineKeyTest, AttestationNotPrepared) { - cryptohome_client_.set_tpm_attestation_is_prepared(false); - - EXPECT_EQ(GetCertificateError(kResetRequired), - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - -// Test that we get proper error message in case we don't have TPM. -TEST_F(EPKPChallengeMachineKeyTest, AttestationUnsupported) { - cryptohome_client_.set_tpm_attestation_is_prepared(false); - cryptohome_client_.set_tpm_is_enabled(false); - - EXPECT_EQ(GetCertificateError(kPrepareKeyAttestationUnsupported), - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - -TEST_F(EPKPChallengeMachineKeyTest, AttestationPreparedDbusFailed) { - cryptohome_client_.SetServiceIsAvailable(false); - - EXPECT_EQ(GetCertificateError(kDBusError), - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - -// Tests the API with all profiles types as determined by the test parameter. -class EPKPChallengeMachineKeyAllProfilesTest - : public EPKPChallengeMachineKeyTest, - public ::testing::WithParamInterface< - EPKPChallengeKeyTestBase::ProfileType> { - protected: - EPKPChallengeMachineKeyAllProfilesTest() - : EPKPChallengeMachineKeyTest(GetParam()) {} -}; - -TEST_P(EPKPChallengeMachineKeyAllProfilesTest, Success) { - // GetCertificate must be called exactly once. - EXPECT_CALL(mock_attestation_flow_, - GetCertificate( - chromeos::attestation::PROFILE_ENTERPRISE_MACHINE_CERTIFICATE, - _, _, _, _, _)) - .Times(1); - // SignEnterpriseChallenge must be called exactly once. - EXPECT_CALL(mock_async_method_caller_, - TpmAttestationSignEnterpriseChallenge( - chromeos::attestation::KEY_DEVICE, - cryptohome::Identification(), "attest-ent-machine", - "google.com", "device_id", _, "challenge", _, _)) - .Times(1); + base::ListValue whitelist; + whitelist.AppendString(extension_->id()); + prefs_->Set(prefs::kAttestationExtensionWhitelist, whitelist); std::unique_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult( - func_.get(), kArgs, browser(), extensions::api_test_utils::NONE)); + func_.get(), kFuncArgs, browser(), extensions::api_test_utils::NONE)); std::string response; value->GetAsString(&response); EXPECT_EQ("cmVzcG9uc2U=" /* Base64 encoding of 'response' */, response); } -INSTANTIATE_TEST_SUITE_P( - AllProfiles, - EPKPChallengeMachineKeyAllProfilesTest, - ::testing::Values(EPKPChallengeKeyTestBase::ProfileType::USER_PROFILE, - EPKPChallengeKeyTestBase::ProfileType::SIGNIN_PROFILE)); - class EPKPChallengeUserKeyTest : public EPKPChallengeKeyTestBase { protected: - static const char kArgs[]; - - explicit EPKPChallengeUserKeyTest( - ProfileType profile_type = ProfileType::USER_PROFILE) - : EPKPChallengeKeyTestBase(profile_type), - impl_(&cryptohome_client_, - &mock_async_method_caller_, - &mock_attestation_flow_, - &stub_install_attributes_), - func_( - new EnterprisePlatformKeysPrivateChallengeUserKeyFunction(&impl_)) { - func_->set_extension(extension_.get()); - } + static const char kFuncArgs[]; - void SetUp() override { - EPKPChallengeKeyTestBase::SetUp(); - - if (profile_type_ == ProfileType::USER_PROFILE) { - // Set the user preferences. - prefs_->SetBoolean(prefs::kAttestationEnabled, true); - } - } - - // Returns an error string for the given code. - std::string GetCertificateError(int error_code) { - return base::StringPrintf(EPKPChallengeUserKey::kGetCertificateFailedError, - error_code); + EPKPChallengeUserKeyTest() + : func_(new EnterprisePlatformKeysPrivateChallengeUserKeyFunction()) { + func_->set_extension(extension_.get()); } - EPKPChallengeUserKey impl_; scoped_refptr<EnterprisePlatformKeysPrivateChallengeUserKeyFunction> func_; }; -// Base 64 encoding of 'challenge' -const char EPKPChallengeUserKeyTest::kArgs[] = "[\"Y2hhbGxlbmdl\", true]"; - -TEST_F(EPKPChallengeUserKeyTest, ChallengeBadBase64) { - EXPECT_EQ(EPKPChallengeKeyBase::kChallengeBadBase64Error, - utils::RunFunctionAndReturnError( - func_.get(), "[\"****\", true]", browser())); -} - -TEST_F(EPKPChallengeUserKeyTest, UserPolicyDisabled) { - prefs_->SetBoolean(prefs::kAttestationEnabled, false); - - EXPECT_EQ(EPKPChallengeUserKey::kUserPolicyDisabledError, - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} +// Base 64 encoding of 'challenge', register_key required. +const char EPKPChallengeUserKeyTest::kFuncArgs[] = "[\"Y2hhbGxlbmdl\", true]"; TEST_F(EPKPChallengeUserKeyTest, ExtensionNotWhitelisted) { base::ListValue empty_whitelist; prefs_->Set(prefs::kAttestationExtensionWhitelist, empty_whitelist); - EXPECT_EQ(EPKPChallengeKeyBase::kExtensionNotWhitelistedError, - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - -TEST_F(EPKPChallengeUserKeyTest, DevicePolicyDisabled) { - settings_helper_.SetBoolean(chromeos::kDeviceAttestationEnabled, false); - - EXPECT_EQ(EPKPChallengeKeyBase::kDevicePolicyDisabledError, - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - -TEST_F(EPKPChallengeUserKeyTest, DoesKeyExistDbusFailed) { - cryptohome_client_.set_tpm_attestation_does_key_exist_should_succeed(false); - - EXPECT_EQ(GetCertificateError(kDBusError), - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - -TEST_F(EPKPChallengeUserKeyTest, GetCertificateFailedWithUnspecifiedFailure) { - EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _)) - .WillRepeatedly(Invoke(GetCertificateCallbackUnspecifiedFailure)); - - EXPECT_EQ(GetCertificateError(kGetCertificateFailed), - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - -TEST_F(EPKPChallengeUserKeyTest, GetCertificateFailedWithBadRequestFailure) { - EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _)) - .WillRepeatedly(Invoke(GetCertificateCallbackBadRequestFailure)); - - EXPECT_EQ(GetCertificateError(kGetCertificateFailed), - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - -TEST_F(EPKPChallengeUserKeyTest, SignChallengeFailed) { - EXPECT_CALL(mock_async_method_caller_, - TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _, _)) - .WillRepeatedly(Invoke(SignChallengeCallbackFalse)); - - EXPECT_EQ(EPKPChallengeKeyBase::kSignChallengeFailedError, - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - -TEST_F(EPKPChallengeUserKeyTest, KeyRegistrationFailed) { - EXPECT_CALL(mock_async_method_caller_, TpmAttestationRegisterKey(_, _, _, _)) - .WillRepeatedly(Invoke(RegisterKeyCallbackFalse)); - - EXPECT_EQ(EPKPChallengeUserKey::kKeyRegistrationFailedError, - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - -TEST_F(EPKPChallengeUserKeyTest, KeyExists) { - cryptohome_client_.SetTpmAttestationUserCertificate( - cryptohome::CreateAccountIdentifierFromAccountId( - AccountId::FromUserEmail(kUserEmail)), - "attest-ent-user", std::string()); - // GetCertificate must not be called if the key exists. - EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _)) - .Times(0); - - EXPECT_TRUE(utils::RunFunction(func_.get(), kArgs, browser(), - extensions::api_test_utils::NONE)); -} - -TEST_F(EPKPChallengeUserKeyTest, KeyNotRegistered) { - EXPECT_CALL(mock_async_method_caller_, TpmAttestationRegisterKey(_, _, _, _)) - .Times(0); - - EXPECT_TRUE(utils::RunFunction(func_.get(), "[\"Y2hhbGxlbmdl\", false]", - browser(), extensions::api_test_utils::NONE)); -} - -TEST_F(EPKPChallengeUserKeyTest, PersonalDevice) { - stub_install_attributes_.SetConsumerOwned(); - - // Currently personal devices are not supported. - EXPECT_EQ(GetCertificateError(kUserRejected), - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); + EXPECT_EQ( + EPKPChallengeKey::kExtensionNotWhitelistedError, + utils::RunFunctionAndReturnError(func_.get(), kFuncArgs, browser())); } TEST_F(EPKPChallengeUserKeyTest, Success) { - // GetCertificate must be called exactly once. - EXPECT_CALL( - mock_attestation_flow_, - GetCertificate(chromeos::attestation::PROFILE_ENTERPRISE_USER_CERTIFICATE, - _, _, _, _, _)) - .Times(1); - const AccountId account_id = AccountId::FromUserEmail(kUserEmail); - // SignEnterpriseChallenge must be called exactly once. - EXPECT_CALL(mock_async_method_caller_, - TpmAttestationSignEnterpriseChallenge( - chromeos::attestation::KEY_USER, - cryptohome::Identification(account_id), "attest-ent-user", - cryptohome::Identification(account_id).id(), "device_id", _, - "challenge", _, _)) - .Times(1); - // RegisterKey must be called exactly once. - EXPECT_CALL(mock_async_method_caller_, - TpmAttestationRegisterKey(chromeos::attestation::KEY_USER, - cryptohome::Identification(account_id), - "attest-ent-user", _)) - .Times(1); + SetMockTpmChallenger(); + + base::ListValue whitelist; + whitelist.AppendString(extension_->id()); + prefs_->Set(prefs::kAttestationExtensionWhitelist, whitelist); std::unique_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult( - func_.get(), kArgs, browser(), extensions::api_test_utils::NONE)); + func_.get(), kFuncArgs, browser(), extensions::api_test_utils::NONE)); std::string response; value->GetAsString(&response); EXPECT_EQ("cmVzcG9uc2U=" /* Base64 encoding of 'response' */, response); } -TEST_F(EPKPChallengeUserKeyTest, AttestationNotPrepared) { - cryptohome_client_.set_tpm_attestation_is_prepared(false); - - EXPECT_EQ(GetCertificateError(kResetRequired), - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - -TEST_F(EPKPChallengeUserKeyTest, AttestationPreparedDbusFailed) { - cryptohome_client_.SetServiceIsAvailable(false); - - EXPECT_EQ(GetCertificateError(kDBusError), - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - -class EPKPChallengeUserKeySigninProfileTest : public EPKPChallengeUserKeyTest { - protected: - EPKPChallengeUserKeySigninProfileTest() - : EPKPChallengeUserKeyTest(ProfileType::SIGNIN_PROFILE) {} -}; - -TEST_F(EPKPChallengeUserKeySigninProfileTest, UserKeyNotAvailable) { - settings_helper_.SetBoolean(chromeos::kDeviceAttestationEnabled, false); - - EXPECT_EQ(EPKPChallengeUserKey::kUserKeyNotAvailable, - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - -class EPKPChallengeMachineKeyUnmanagedUserTest - : public EPKPChallengeMachineKeyTest { - protected: - void SetAuthenticatedUser() override { - auto* identity_manager = - IdentityManagerFactory::GetForProfile(browser()->profile()); - signin::MakePrimaryAccountAvailable(identity_manager, - account_id_.GetUserEmail()); - } - - TestingProfile* CreateProfile() override { - fake_user_manager_->AddUser(account_id_); - return profile_manager()->CreateTestingProfile(account_id_.GetUserEmail()); - } - - private: - const std::string kOtherEmail = "test@chromium.com"; - const AccountId account_id_ = AccountId::FromUserEmailGaiaId( - kOtherEmail, - signin::GetTestGaiaIdForEmail(kOtherEmail)); -}; - -TEST_F(EPKPChallengeMachineKeyUnmanagedUserTest, UserNotManaged) { - EXPECT_EQ(EPKPChallengeKeyBase::kUserNotManaged, - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - -class EPKPChallengeUserKeyUnmanagedUserTest : public EPKPChallengeUserKeyTest { - protected: - void SetAuthenticatedUser() override { - auto* identity_manager = - IdentityManagerFactory::GetForProfile(browser()->profile()); - signin::MakePrimaryAccountAvailable(identity_manager, - account_id_.GetUserEmail()); - } - - TestingProfile* CreateProfile() override { - fake_user_manager_->AddUser(account_id_); - return profile_manager()->CreateTestingProfile(account_id_.GetUserEmail()); - } - - private: - const std::string kOtherEmail = "test@chromium.com"; - const AccountId account_id_ = AccountId::FromUserEmailGaiaId( - kOtherEmail, - signin::GetTestGaiaIdForEmail(kOtherEmail)); -}; - -TEST_F(EPKPChallengeUserKeyUnmanagedUserTest, UserNotManaged) { - EXPECT_EQ(EPKPChallengeKeyBase::kUserNotManaged, - utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); -} - } // namespace } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc b/chromium/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc index e8a2d2d10f7..f3052240da4 100644 --- a/chromium/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc +++ b/chromium/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc @@ -38,6 +38,7 @@ #include "components/prefs/pref_service.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/notification_service.h" +#include "content/public/browser/overlay_window.h" #include "content/public/browser/picture_in_picture_window_controller.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" diff --git a/chromium/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc b/chromium/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc index 8fd11ee84dd..5d765101e1b 100644 --- a/chromium/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc +++ b/chromium/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc @@ -26,7 +26,6 @@ #include "content/public/browser/host_zoom_map.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" -#include "content/public/common/page_zoom.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/notification_types.h" #include "extensions/common/extension.h" @@ -34,6 +33,7 @@ #include "extensions/common/permissions/permissions_data.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" +#include "third_party/blink/public/common/page/page_zoom.h" #include "ui/base/buildflags.h" #if defined(OS_WIN) @@ -465,13 +465,13 @@ IN_PROC_BROWSER_TEST_F(BrowserActionInteractiveTest, PopupZoomsIndependently) { content::HostZoomMap::GetForWebContents(popup_contents) ->GetDefaultZoomLevel(); double popup_zoom_level = content::HostZoomMap::GetZoomLevel(popup_contents); - EXPECT_TRUE(content::ZoomValuesEqual(popup_zoom_level, default_zoom_level)) + EXPECT_TRUE(blink::PageZoomValuesEqual(popup_zoom_level, default_zoom_level)) << popup_zoom_level << " vs " << default_zoom_level; // Preventing the use of the per-origin zoom level in the popup should not // affect the zoom of the tab. - EXPECT_TRUE(content::ZoomValuesEqual(zoom_controller->GetZoomLevel(), - tab_new_zoom_level)) + EXPECT_TRUE(blink::PageZoomValuesEqual(zoom_controller->GetZoomLevel(), + tab_new_zoom_level)) << zoom_controller->GetZoomLevel() << " vs " << tab_new_zoom_level; // Subsequent zooming in the tab should also be done independently of the @@ -487,7 +487,7 @@ IN_PROC_BROWSER_TEST_F(BrowserActionInteractiveTest, PopupZoomsIndependently) { zoom_change_watcher2.Wait(); popup_zoom_level = content::HostZoomMap::GetZoomLevel(popup_contents); - EXPECT_TRUE(content::ZoomValuesEqual(popup_zoom_level, default_zoom_level)) + EXPECT_TRUE(blink::PageZoomValuesEqual(popup_zoom_level, default_zoom_level)) << popup_zoom_level << " vs " << default_zoom_level; ClosePopup(); diff --git a/chromium/chrome/browser/extensions/api/file_system/file_system_apitest.cc b/chromium/chrome/browser/extensions/api/file_system/file_system_apitest.cc index 0c5ea4b2b75..d624301ffc8 100644 --- a/chromium/chrome/browser/extensions/api/file_system/file_system_apitest.cc +++ b/chromium/chrome/browser/extensions/api/file_system/file_system_apitest.cc @@ -33,7 +33,7 @@ class AppLoadObserver : public ExtensionRegistryObserver { public: AppLoadObserver(content::BrowserContext* browser_context, base::Callback<void(const Extension*)> callback) - : callback_(callback), extension_registry_observer_(this) { + : callback_(callback) { extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context)); } @@ -45,7 +45,7 @@ class AppLoadObserver : public ExtensionRegistryObserver { private: base::Callback<void(const Extension*)> callback_; ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - extension_registry_observer_; + extension_registry_observer_{this}; DISALLOW_COPY_AND_ASSIGN(AppLoadObserver); }; diff --git a/chromium/chrome/browser/extensions/api/file_system/file_system_apitest_chromeos.cc b/chromium/chrome/browser/extensions/api/file_system/file_system_apitest_chromeos.cc index 2b6050668d3..a3eab8edb33 100644 --- a/chromium/chrome/browser/extensions/api/file_system/file_system_apitest_chromeos.cc +++ b/chromium/chrome/browser/extensions/api/file_system/file_system_apitest_chromeos.cc @@ -144,16 +144,6 @@ class FileSystemApiTestForDrive : public PlatformAppBrowserTest { // necessary because the fetch starts lazily upon the first read operation. void SetUpOnMainThread() override { PlatformAppBrowserTest::SetUpOnMainThread(); - - if (!base::FeatureList::IsEnabled(chromeos::features::kDriveFs)) { - std::unique_ptr<drive::ResourceEntry> entry; - drive::FileError error = drive::FILE_ERROR_FAILED; - integration_service_->file_system()->GetResourceEntry( - base::FilePath::FromUTF8Unsafe("drive/root"), // whatever - google_apis::test_util::CreateCopyResultCallback(&error, &entry)); - content::RunAllTasksUntilIdle(); - ASSERT_EQ(drive::FILE_ERROR_OK, error); - } } void TearDown() override { @@ -161,13 +151,7 @@ class FileSystemApiTestForDrive : public PlatformAppBrowserTest { PlatformAppBrowserTest::TearDown(); } - base::FilePath GetDriveMountPoint() { - if (base::FeatureList::IsEnabled(chromeos::features::kDriveFs)) { - return drivefs_mount_point_; - } else { - return drive::util::GetDriveMountPointPath(browser()->profile()); - } - } + base::FilePath GetDriveMountPoint() { return drivefs_mount_point_; } private: drive::DriveIntegrationService* CreateDriveIntegrationService( diff --git a/chromium/chrome/browser/extensions/api/history/history_api.cc b/chromium/chrome/browser/extensions/api/history/history_api.cc index 010b8478e82..1692d8d951e 100644 --- a/chromium/chrome/browser/extensions/api/history/history_api.cc +++ b/chromium/chrome/browser/extensions/api/history/history_api.cc @@ -132,7 +132,7 @@ VisitItem GetVisitItem(const history::VisitRow& row) { HistoryEventRouter::HistoryEventRouter(Profile* profile, history::HistoryService* history_service) - : profile_(profile), history_service_observer_(this) { + : profile_(profile) { DCHECK(profile); history_service_observer_.Add(history_service); } diff --git a/chromium/chrome/browser/extensions/api/history/history_api.h b/chromium/chrome/browser/extensions/api/history/history_api.h index 5349fca6a52..8c3814eee95 100644 --- a/chromium/chrome/browser/extensions/api/history/history_api.h +++ b/chromium/chrome/browser/extensions/api/history/history_api.h @@ -13,6 +13,7 @@ #include "base/scoped_observer.h" #include "base/task/cancelable_task_tracker.h" #include "chrome/common/extensions/api/history.h" +#include "components/history/core/browser/history_service.h" #include "components/history/core/browser/history_service_observer.h" #include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/event_router.h" @@ -24,10 +25,6 @@ namespace base { class ListValue; } -namespace history { -class HistoryService; -} - namespace extensions { // Observes History service and routes the notifications as events to the @@ -55,7 +52,7 @@ class HistoryEventRouter : public history::HistoryServiceObserver { Profile* profile_; ScopedObserver<history::HistoryService, history::HistoryServiceObserver> - history_service_observer_; + history_service_observer_{this}; DISALLOW_COPY_AND_ASSIGN(HistoryEventRouter); }; diff --git a/chromium/chrome/browser/extensions/api/identity/extension_token_key.cc b/chromium/chrome/browser/extensions/api/identity/extension_token_key.cc index 08f81d01c1e..351ec13198d 100644 --- a/chromium/chrome/browser/extensions/api/identity/extension_token_key.cc +++ b/chromium/chrome/browser/extensions/api/identity/extension_token_key.cc @@ -9,7 +9,7 @@ namespace extensions { ExtensionTokenKey::ExtensionTokenKey(const std::string& extension_id, - const std::string& account_id, + const CoreAccountId& account_id, const std::set<std::string>& scopes) : extension_id(extension_id), account_id(account_id), scopes(scopes) {} diff --git a/chromium/chrome/browser/extensions/api/identity/extension_token_key.h b/chromium/chrome/browser/extensions/api/identity/extension_token_key.h index d722dee8a57..39c0a439a57 100644 --- a/chromium/chrome/browser/extensions/api/identity/extension_token_key.h +++ b/chromium/chrome/browser/extensions/api/identity/extension_token_key.h @@ -8,17 +8,19 @@ #include <set> #include <string> +#include "google_apis/gaia/core_account_id.h" + namespace extensions { struct ExtensionTokenKey { ExtensionTokenKey(const std::string& extension_id, - const std::string& account_id, + const CoreAccountId& account_id, const std::set<std::string>& scopes); ExtensionTokenKey(const ExtensionTokenKey& other); ~ExtensionTokenKey(); bool operator<(const ExtensionTokenKey& rhs) const; std::string extension_id; - std::string account_id; + CoreAccountId account_id; std::set<std::string> scopes; }; diff --git a/chromium/chrome/browser/extensions/api/identity/extension_token_key_unittest.cc b/chromium/chrome/browser/extensions/api/identity/extension_token_key_unittest.cc index aaedbd3bea4..cc2638bce5d 100644 --- a/chromium/chrome/browser/extensions/api/identity/extension_token_key_unittest.cc +++ b/chromium/chrome/browser/extensions/api/identity/extension_token_key_unittest.cc @@ -26,9 +26,9 @@ TEST(IdentityExtensionTokenKeyTest, Ordering) { extension_ids.push_back(extension_id1); extension_ids.push_back(extension_id2); - std::vector<std::string> user_ids; - user_ids.push_back("user_id_1"); - user_ids.push_back("user_id_2"); + std::vector<CoreAccountId> user_ids; + user_ids.push_back(CoreAccountId("user_id_1")); + user_ids.push_back(CoreAccountId("user_id_2")); std::vector<std::set<std::string> > scopesets; scopesets.push_back(scopes1); @@ -40,7 +40,7 @@ TEST(IdentityExtensionTokenKeyTest, Ordering) { ExtensionTokenKeyIterator; std::vector<std::string>::const_iterator extension_it; - std::vector<std::string>::const_iterator user_it; + std::vector<CoreAccountId>::const_iterator user_it; std::vector<std::set<std::string> >::const_iterator scope_it; for (extension_it = extension_ids.begin(); diff --git a/chromium/chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc b/chromium/chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc index 63053cac503..f8677cb1515 100644 --- a/chromium/chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc +++ b/chromium/chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc @@ -30,13 +30,9 @@ GaiaWebAuthFlow::GaiaWebAuthFlow(Delegate* delegate, : delegate_(delegate), profile_(profile), account_id_(token_key->account_id) { - TRACE_EVENT_ASYNC_BEGIN2("identity", - "GaiaWebAuthFlow", - this, - "extension_id", - token_key->extension_id, - "account_id", - token_key->account_id); + TRACE_EVENT_ASYNC_BEGIN2("identity", "GaiaWebAuthFlow", this, "extension_id", + token_key->extension_id, "account_id", + token_key->account_id.id); const char kOAuth2RedirectPathFormat[] = "/%s"; const char kOAuth2AuthorizeFormat[] = diff --git a/chromium/chrome/browser/extensions/api/identity/gaia_web_auth_flow.h b/chromium/chrome/browser/extensions/api/identity/gaia_web_auth_flow.h index 8ba5fa6780f..037ac0cd0b8 100644 --- a/chromium/chrome/browser/extensions/api/identity/gaia_web_auth_flow.h +++ b/chromium/chrome/browser/extensions/api/identity/gaia_web_auth_flow.h @@ -89,7 +89,7 @@ class GaiaWebAuthFlow : public WebAuthFlow::Delegate { Delegate* delegate_; Profile* profile_; - std::string account_id_; + CoreAccountId account_id_; std::string redirect_scheme_; std::string redirect_path_prefix_; GURL auth_url_; diff --git a/chromium/chrome/browser/extensions/api/identity/identity_apitest.cc b/chromium/chrome/browser/extensions/api/identity/identity_apitest.cc index ef79b4e60e5..9a1ff1ad423 100644 --- a/chromium/chrome/browser/extensions/api/identity/identity_apitest.cc +++ b/chromium/chrome/browser/extensions/api/identity/identity_apitest.cc @@ -485,7 +485,7 @@ class IdentityTestWithSignin : public AsyncExtensionBrowserTest { protected: // Returns the account ID of the created account. - std::string SignIn(const std::string& email) { + CoreAccountId SignIn(const std::string& email) { auto account_info = identity_test_env()->MakePrimaryAccountAvailable(email); return account_info.account_id; } @@ -606,7 +606,7 @@ IN_PROC_BROWSER_TEST_F(IdentityGetAccountsFunctionTest, NoPrimaryAccount) { IN_PROC_BROWSER_TEST_F(IdentityGetAccountsFunctionTest, PrimaryAccountHasNoRefreshToken) { - std::string primary_account_id = SignIn("primary@example.com"); + CoreAccountId primary_account_id = SignIn("primary@example.com"); identity_test_env()->RemoveRefreshTokenForAccount(primary_account_id); EXPECT_TRUE(ExpectGetAccounts({})); } @@ -776,7 +776,7 @@ class GetAuthTokenFunctionTest return ext; } - std::string GetPrimaryAccountId() { + CoreAccountId GetPrimaryAccountId() { return identity_test_env()->identity_manager()->GetPrimaryAccountId(); } @@ -785,13 +785,14 @@ class GetAuthTokenFunctionTest SetCachedTokenForAccount(GetPrimaryAccountId(), token_data); } - void SetCachedTokenForAccount(const std::string account_id, + void SetCachedTokenForAccount(const CoreAccountId account_id, const IdentityTokenCacheValue& token_data) { ExtensionTokenKey key(extension_id_, account_id, oauth_scopes_); id_api()->SetCachedToken(key, token_data); } - const IdentityTokenCacheValue& GetCachedToken(const std::string& account_id) { + const IdentityTokenCacheValue& GetCachedToken( + const CoreAccountId& account_id) { ExtensionTokenKey key( extension_id_, account_id.empty() ? GetPrimaryAccountId() : account_id, oauth_scopes_); @@ -933,7 +934,7 @@ IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, EXPECT_FALSE(func->scope_ui_shown()); EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_ADVICE, - GetCachedToken(std::string()).status()); + GetCachedToken(CoreAccountId()).status()); } IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, @@ -1019,7 +1020,7 @@ IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, NoOptionsSuccess) { EXPECT_FALSE(func->login_ui_shown()); EXPECT_FALSE(func->scope_ui_shown()); EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN, - GetCachedToken(std::string()).status()); + GetCachedToken(CoreAccountId()).status()); } IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, NonInteractiveSuccess) { @@ -1036,7 +1037,7 @@ IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, NonInteractiveSuccess) { EXPECT_FALSE(func->login_ui_shown()); EXPECT_FALSE(func->scope_ui_shown()); EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN, - GetCachedToken(std::string()).status()); + GetCachedToken(CoreAccountId()).status()); } IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, InteractiveLoginCanceled) { @@ -1310,7 +1311,7 @@ IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, InteractiveApprovalSuccess) { EXPECT_TRUE(func->scope_ui_shown()); EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN, - GetCachedToken(std::string()).status()); + GetCachedToken(CoreAccountId()).status()); } #if !defined(OS_MACOSX) @@ -1634,7 +1635,7 @@ IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, LoginInvalidatesTokenCache) { EXPECT_TRUE(func->login_ui_shown()); EXPECT_TRUE(func->scope_ui_shown()); EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND, - GetCachedToken(std::string()).status()); + GetCachedToken(CoreAccountId()).status()); } #endif @@ -1716,7 +1717,7 @@ IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, } IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, ManuallyIssueToken) { - std::string primary_account_id = SignIn("primary@example.com"); + CoreAccountId primary_account_id = SignIn("primary@example.com"); scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction()); scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES)); @@ -1739,12 +1740,12 @@ IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, ManuallyIssueToken) { EXPECT_TRUE(value->GetAsString(&access_token)); EXPECT_EQ(std::string(kAccessToken), access_token); EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN, - GetCachedToken(std::string()).status()); + GetCachedToken(CoreAccountId()).status()); EXPECT_EQ(primary_account_access_token, func->login_access_token()); } IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, ManuallyIssueTokenFailure) { - std::string primary_account_id = SignIn("primary@example.com"); + CoreAccountId primary_account_id = SignIn("primary@example.com"); scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction()); scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES)); @@ -1772,7 +1773,7 @@ IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, ManuallyIssueTokenFailure) { IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, MultiDefaultUserManuallyIssueToken) { - std::string primary_account_id = SignIn("primary@example.com"); + CoreAccountId primary_account_id = SignIn("primary@example.com"); identity_test_env()->MakeAccountAvailable("secondary@example.com"); scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction()); @@ -1794,13 +1795,13 @@ IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, EXPECT_TRUE(value->GetAsString(&access_token)); EXPECT_EQ(std::string(kAccessToken), access_token); EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN, - GetCachedToken(std::string()).status()); + GetCachedToken(CoreAccountId()).status()); EXPECT_EQ(primary_account_access_token, func->login_access_token()); } IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, MultiPrimaryUserManuallyIssueToken) { - std::string primary_account_id = SignIn("primary@example.com"); + CoreAccountId primary_account_id = SignIn("primary@example.com"); identity_test_env()->MakeAccountAvailable("secondary@example.com"); scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction()); @@ -1824,7 +1825,7 @@ IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, EXPECT_TRUE(value->GetAsString(&access_token)); EXPECT_EQ(std::string(kAccessToken), access_token); EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN, - GetCachedToken(std::string()).status()); + GetCachedToken(CoreAccountId()).status()); EXPECT_EQ(primary_account_access_token, func->login_access_token()); } @@ -1834,8 +1835,8 @@ IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, if (id_api()->AreExtensionsRestrictedToPrimaryAccount()) return; - std::string primary_account_id = SignIn("primary@example.com"); - std::string secondary_account_id = + SignIn("primary@example.com"); + CoreAccountId secondary_account_id = identity_test_env() ->MakeAccountAvailable("secondary@example.com") .account_id; @@ -2141,14 +2142,15 @@ class RemoveCachedAuthTokenFunctionTest : public ExtensionBrowserTest { } void SetCachedToken(const IdentityTokenCacheValue& token_data) { - ExtensionTokenKey key(kExtensionId, "test@example.com", + ExtensionTokenKey key(kExtensionId, CoreAccountId("test@example.com"), std::set<std::string>()); id_api()->SetCachedToken(key, token_data); } const IdentityTokenCacheValue& GetCachedToken() { - return id_api()->GetCachedToken(ExtensionTokenKey( - kExtensionId, "test@example.com", std::set<std::string>())); + return id_api()->GetCachedToken( + ExtensionTokenKey(kExtensionId, CoreAccountId("test@example.com"), + std::set<std::string>())); } }; @@ -2450,7 +2452,7 @@ IN_PROC_BROWSER_TEST_F(OnSignInChangedEventTest, account_info.id = "gaia_id_for_primary_example.com"; AddExpectedEvent(api::identity::OnSignInChanged::Create(account_info, true)); - std::string primary_account_id = SignIn("primary@example.com"); + CoreAccountId primary_account_id = SignIn("primary@example.com"); AddExpectedEvent(api::identity::OnSignInChanged::Create(account_info, false)); @@ -2468,7 +2470,7 @@ IN_PROC_BROWSER_TEST_F(OnSignInChangedEventTest, account_info.id = "gaia_id_for_primary_example.com"; AddExpectedEvent(api::identity::OnSignInChanged::Create(account_info, true)); - std::string primary_account_id = SignIn("primary@example.com"); + CoreAccountId primary_account_id = SignIn("primary@example.com"); AddExpectedEvent(api::identity::OnSignInChanged::Create(account_info, false)); identity_test_env()->RemoveRefreshTokenForAccount(primary_account_id); diff --git a/chromium/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc b/chromium/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc index 1de99c202c3..5ef4deb52ad 100644 --- a/chromium/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc +++ b/chromium/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc @@ -14,6 +14,7 @@ #include "base/task/post_task.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/extensions/api/identity/identity_api.h" #include "chrome/browser/extensions/api/identity/identity_constants.h" #include "chrome/browser/profiles/profile.h" @@ -76,7 +77,7 @@ IdentityGetAuthTokenFunction::IdentityGetAuthTokenFunction() should_prompt_for_scopes_(false), should_prompt_for_signin_(false), token_key_(/*extension_id=*/std::string(), - /*account_id=*/std::string(), + /*account_id=*/CoreAccountId(), /*scopes=*/std::set<std::string>()), scoped_identity_manager_observer_(this) { } @@ -205,7 +206,8 @@ void IdentityGetAuthTokenFunction::FetchExtensionAccountInfo( void IdentityGetAuthTokenFunction::OnReceivedExtensionAccountInfo( const CoreAccountInfo* account_info) { - token_key_.account_id = account_info ? account_info->account_id : ""; + token_key_.account_id = + account_info ? account_info->account_id : CoreAccountId(); #if defined(OS_CHROMEOS) policy::BrowserPolicyConnectorChromeOS* connector = @@ -675,7 +677,7 @@ void IdentityGetAuthTokenFunction::OnGetAccessTokenComplete( if (access_token) { TRACE_EVENT_ASYNC_STEP_PAST1("identity", "IdentityGetAuthTokenFunction", this, "OnGetAccessTokenComplete", "account", - token_key_.account_id); + token_key_.account_id.id); StartGaiaRequest(access_token.value()); } else { diff --git a/chromium/chrome/browser/extensions/api/identity/identity_mint_queue_unittest.cc b/chromium/chrome/browser/extensions/api/identity/identity_mint_queue_unittest.cc index 3dd5952dfe2..b77326da9a8 100644 --- a/chromium/chrome/browser/extensions/api/identity/identity_mint_queue_unittest.cc +++ b/chromium/chrome/browser/extensions/api/identity/identity_mint_queue_unittest.cc @@ -22,8 +22,8 @@ class MockRequest : public extensions::IdentityMintRequestQueue::Request { std::unique_ptr<ExtensionTokenKey> ExtensionIdToKey( const std::string& extension_id) { - return std::unique_ptr<ExtensionTokenKey>( - new ExtensionTokenKey(extension_id, "user_id", std::set<std::string>())); + return std::unique_ptr<ExtensionTokenKey>(new ExtensionTokenKey( + extension_id, CoreAccountId("user_id"), std::set<std::string>())); } } // namespace diff --git a/chromium/chrome/browser/extensions/api/image_writer_private/operation_manager.cc b/chromium/chrome/browser/extensions/api/image_writer_private/operation_manager.cc index f0dbae03359..e8010124b5d 100644 --- a/chromium/chrome/browser/extensions/api/image_writer_private/operation_manager.cc +++ b/chromium/chrome/browser/extensions/api/image_writer_private/operation_manager.cc @@ -23,7 +23,6 @@ #include "content/public/browser/storage_partition.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_host.h" -#include "extensions/browser/extension_registry.h" #include "extensions/browser/notification_types.h" #if defined(OS_CHROMEOS) @@ -38,7 +37,7 @@ namespace image_writer { using content::BrowserThread; OperationManager::OperationManager(content::BrowserContext* context) - : browser_context_(context), extension_registry_observer_(this) { + : browser_context_(context) { extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); Profile* profile = Profile::FromBrowserContext(browser_context_); registrar_.Add(this, diff --git a/chromium/chrome/browser/extensions/api/image_writer_private/operation_manager.h b/chromium/chrome/browser/extensions/api/image_writer_private/operation_manager.h index ae2a04f5658..f45645f523c 100644 --- a/chromium/chrome/browser/extensions/api/image_writer_private/operation_manager.h +++ b/chromium/chrome/browser/extensions/api/image_writer_private/operation_manager.h @@ -18,6 +18,7 @@ #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "extensions/browser/browser_context_keyed_api_factory.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry_observer.h" #include "extensions/common/extension_id.h" #include "url/gurl.h" @@ -29,7 +30,6 @@ class BrowserContext; } namespace extensions { -class ExtensionRegistry; namespace image_writer { @@ -116,7 +116,7 @@ class OperationManager : public BrowserContextKeyedAPI, // Listen to extension unloaded notification. ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - extension_registry_observer_; + extension_registry_observer_{this}; base::WeakPtrFactory<OperationManager> weak_factory_{this}; diff --git a/chromium/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_chromeos_unittest.cc b/chromium/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_chromeos_unittest.cc index 431c9e43557..af1d4c4852b 100644 --- a/chromium/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_chromeos_unittest.cc +++ b/chromium/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_chromeos_unittest.cc @@ -15,9 +15,6 @@ namespace extensions { namespace { -using namespace chromeos::disks; -using namespace api::image_writer_private; - const char kDevicePathUSB[] = "/dev/test-usb"; const char kDevicePathSD[] = "/dev/test-sd"; const char kMountPath[] = "/test-mount"; @@ -36,12 +33,13 @@ class RemovableStorageProviderChromeOsUnitTest : public testing::Test { public: RemovableStorageProviderChromeOsUnitTest() {} void SetUp() override { - disk_mount_manager_mock_ = new MockDiskMountManager(); - DiskMountManager::InitializeForTesting(disk_mount_manager_mock_); + disk_mount_manager_mock_ = new chromeos::disks::MockDiskMountManager(); + chromeos::disks::DiskMountManager::InitializeForTesting( + disk_mount_manager_mock_); disk_mount_manager_mock_->SetupDefaultReplies(); } - void TearDown() override { DiskMountManager::Shutdown(); } + void TearDown() override { chromeos::disks::DiskMountManager::Shutdown(); } void DevicesCallback(scoped_refptr<StorageDeviceList> devices) { devices_ = devices; @@ -68,10 +66,8 @@ class RemovableStorageProviderChromeOsUnitTest : public testing::Test { bool is_parent, bool has_media, bool on_boot_device) { - DiskMountManager::MountPointInfo mount_info( - device_path, - kMountPath, - chromeos::MOUNT_TYPE_DEVICE, + chromeos::disks::DiskMountManager::MountPointInfo mount_info( + device_path, kMountPath, chromeos::MOUNT_TYPE_DEVICE, chromeos::disks::MOUNT_CONDITION_NONE); disk_mount_manager_mock_->CreateDiskEntryForMountDevice( mount_info, kDeviceId, kDeviceName, vendor_name, product_name, @@ -80,13 +76,14 @@ class RemovableStorageProviderChromeOsUnitTest : public testing::Test { } // Checks if the DeviceList has a specific entry. - RemovableStorageDevice* FindDevice(StorageDeviceList* list, - const std::string& file_path) { - for (RemovableStorageDevice& device : list->data) { + api::image_writer_private::RemovableStorageDevice* FindDevice( + StorageDeviceList* list, + const std::string& file_path) { + for (auto& device : list->data) { if (device.storage_unit_id == file_path) return &device; } - return NULL; + return nullptr; } void ExpectDevice(StorageDeviceList* list, @@ -94,9 +91,9 @@ class RemovableStorageProviderChromeOsUnitTest : public testing::Test { const std::string& vendor, const std::string& model, uint64_t capacity) { - RemovableStorageDevice* device = FindDevice(devices_.get(), device_path); + auto* device = FindDevice(devices_.get(), device_path); - ASSERT_TRUE(device != NULL); + ASSERT_TRUE(device); EXPECT_EQ(device_path, device->storage_unit_id); EXPECT_EQ(vendor, device->vendor); @@ -105,7 +102,7 @@ class RemovableStorageProviderChromeOsUnitTest : public testing::Test { } content::BrowserTaskEnvironment task_environment_; - MockDiskMountManager* disk_mount_manager_mock_; + chromeos::disks::MockDiskMountManager* disk_mount_manager_mock_; scoped_refptr<StorageDeviceList> devices_; }; diff --git a/chromium/chrome/browser/extensions/api/image_writer_private/test_utils.cc b/chromium/chrome/browser/extensions/api/image_writer_private/test_utils.cc index c7ca25348d9..4828d5cdb23 100644 --- a/chromium/chrome/browser/extensions/api/image_writer_private/test_utils.cc +++ b/chromium/chrome/browser/extensions/api/image_writer_private/test_utils.cc @@ -314,7 +314,7 @@ bool ImageWriterTestUtils::FillFile(const base::FilePath& file, } ImageWriterUnitTestBase::ImageWriterUnitTestBase() - : task_environment_(content::BrowserTaskEnvironment::REAL_IO_THREAD) {} + : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP) {} ImageWriterUnitTestBase::~ImageWriterUnitTestBase() { } diff --git a/chromium/chrome/browser/extensions/api/image_writer_private/write_from_url_operation.cc b/chromium/chrome/browser/extensions/api/image_writer_private/write_from_url_operation.cc index fdebd683504..a5ebd3f0985 100644 --- a/chromium/chrome/browser/extensions/api/image_writer_private/write_from_url_operation.cc +++ b/chromium/chrome/browser/extensions/api/image_writer_private/write_from_url_operation.cc @@ -10,8 +10,8 @@ #include "content/public/browser/browser_thread.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_fetcher.h" -#include "services/network/public/cpp/resource_response.h" #include "services/network/public/cpp/simple_url_loader.h" +#include "services/network/public/mojom/url_response_head.mojom.h" namespace extensions { namespace image_writer { @@ -136,7 +136,7 @@ void WriteFromUrlOperation::DestroySimpleURLLoader() { void WriteFromUrlOperation::OnResponseStarted( const GURL& final_url, - const network::ResourceResponseHead& response_head) { + const network::mojom::URLResponseHead& response_head) { total_response_bytes_ = response_head.content_length; } diff --git a/chromium/chrome/browser/extensions/api/image_writer_private/write_from_url_operation.h b/chromium/chrome/browser/extensions/api/image_writer_private/write_from_url_operation.h index 617f609515a..b35f3654885 100644 --- a/chromium/chrome/browser/extensions/api/image_writer_private/write_from_url_operation.h +++ b/chromium/chrome/browser/extensions/api/image_writer_private/write_from_url_operation.h @@ -9,10 +9,10 @@ #include "chrome/browser/extensions/api/image_writer_private/operation.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" +#include "services/network/public/mojom/url_response_head.mojom-forward.h" #include "url/gurl.h" namespace network { -struct ResourceResponseHead; class SimpleURLLoader; } // namespace network @@ -53,7 +53,7 @@ class WriteFromUrlOperation : public Operation { private: void DestroySimpleURLLoader(); void OnResponseStarted(const GURL& final_url, - const network::ResourceResponseHead& response_head); + const network::mojom::URLResponseHead& response_head); void OnDataDownloaded(uint64_t current); void OnSimpleLoaderComplete(base::FilePath file_path); void VerifyDownloadCompare(base::OnceClosure continuation, diff --git a/chromium/chrome/browser/extensions/api/input_ime/input_ime_api.cc b/chromium/chrome/browser/extensions/api/input_ime/input_ime_api.cc index 9bfb7c8e07c..573d7ebd794 100644 --- a/chromium/chrome/browser/extensions/api/input_ime/input_ime_api.cc +++ b/chromium/chrome/browser/extensions/api/input_ime/input_ime_api.cc @@ -25,7 +25,7 @@ using input_method::InputMethodEngineBase; namespace { const char kInputImeApiErrorEngineNotAvailable[] = "Engine is not available"; const char kInputImeApiErrorSetKeyEventsFail[] = "Could not send key events"; -} +} // namespace namespace ui { ImeObserver::ImeObserver(const std::string& extension_id, Profile* profile) @@ -80,7 +80,7 @@ void ImeObserver::OnBlur(int context_id) { void ImeObserver::OnKeyEvent( const std::string& component_id, const InputMethodEngineBase::KeyboardEvent& event, - IMEEngineHandlerInterface::KeyEventDoneCallback key_data) { + IMEEngineHandlerInterface::KeyEventDoneCallback callback) { if (extension_id_.empty()) return; @@ -89,7 +89,7 @@ void ImeObserver::OnKeyEvent( if (!ShouldForwardKeyEvent()) { // Continue processing the key event so that the physical keyboard can // still work. - std::move(key_data).Run(false); + std::move(callback).Run(false); return; } @@ -99,22 +99,27 @@ void ImeObserver::OnKeyEvent( return; const std::string request_id = event_router->GetEngineIfActive(extension_id_) - ->AddRequest(component_id, std::move(key_data)); + ->AddPendingKeyEvent(component_id, std::move(callback)); input_ime::KeyboardEvent key_data_value; key_data_value.type = input_ime::ParseKeyboardEventType(event.type); - key_data_value.request_id = request_id; - if (!event.extension_id.empty()) - key_data_value.extension_id.reset(new std::string(event.extension_id)); + // For legacy reasons, we still put a |requestID| into the keyData, even + // though there is already a |requestID| argument in OnKeyEvent. + key_data_value.request_id = std::make_unique<std::string>(request_id); + if (!event.extension_id.empty()) { + key_data_value.extension_id = + std::make_unique<std::string>(event.extension_id); + } key_data_value.key = event.key; key_data_value.code = event.code; - key_data_value.alt_key.reset(new bool(event.alt_key)); - key_data_value.ctrl_key.reset(new bool(event.ctrl_key)); - key_data_value.shift_key.reset(new bool(event.shift_key)); - key_data_value.caps_lock.reset(new bool(event.caps_lock)); + key_data_value.alt_key = std::make_unique<bool>(event.alt_key); + key_data_value.altgr_key = std::make_unique<bool>(event.altgr_key); + key_data_value.ctrl_key = std::make_unique<bool>(event.ctrl_key); + key_data_value.shift_key = std::make_unique<bool>(event.shift_key); + key_data_value.caps_lock = std::make_unique<bool>(event.caps_lock); std::unique_ptr<base::ListValue> args( - input_ime::OnKeyEvent::Create(component_id, key_data_value)); + input_ime::OnKeyEvent::Create(component_id, key_data_value, request_id)); DispatchEventToExtension(extensions::events::INPUT_IME_ON_KEY_EVENT, input_ime::OnKeyEvent::kEventName, std::move(args)); @@ -149,10 +154,6 @@ void ImeObserver::OnDeactivated(const std::string& component_id) { void ImeObserver::OnCompositionBoundsChanged( const std::vector<gfx::Rect>& bounds) {} -bool ImeObserver::IsInterestedInKeyEvent() const { - return ShouldForwardKeyEvent(); -} - void ImeObserver::OnSurroundingTextChanged(const std::string& component_id, const std::string& text, int cursor_pos, @@ -266,11 +267,9 @@ InputImeEventRouterFactory* InputImeEventRouterFactory::GetInstance() { return base::Singleton<InputImeEventRouterFactory>::get(); } -InputImeEventRouterFactory::InputImeEventRouterFactory() { -} +InputImeEventRouterFactory::InputImeEventRouterFactory() = default; -InputImeEventRouterFactory::~InputImeEventRouterFactory() { -} +InputImeEventRouterFactory::~InputImeEventRouterFactory() = default; InputImeEventRouter* InputImeEventRouterFactory::GetRouter(Profile* profile) { if (!profile) @@ -400,16 +399,18 @@ ExtensionFunction::ResponseAction InputImeSendKeyEventsFunction::Run() { SendKeyEvents::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(parent_params); const SendKeyEvents::Params::Parameters& params = parent_params->parameters; - std::vector<InputMethodEngineBase::KeyboardEvent> key_data_out; + std::vector<InputMethodEngineBase::KeyboardEvent> key_data_out; + key_data_out.reserve(params.key_data.size()); for (const auto& key_event : params.key_data) { - key_data_out.push_back(InputMethodEngineBase::KeyboardEvent()); + key_data_out.emplace_back(); InputMethodEngineBase::KeyboardEvent& event = key_data_out.back(); event.type = input_ime::ToString(key_event.type); event.key = key_event.key; event.code = key_event.code; event.key_code = key_event.key_code.get() ? *(key_event.key_code) : 0; event.alt_key = key_event.alt_key ? *(key_event.alt_key) : false; + event.altgr_key = key_event.altgr_key ? *(key_event.altgr_key) : false; event.ctrl_key = key_event.ctrl_key ? *(key_event.ctrl_key) : false; event.shift_key = key_event.shift_key ? *(key_event.shift_key) : false; event.caps_lock = key_event.caps_lock ? *(key_event.caps_lock) : false; @@ -420,7 +421,7 @@ ExtensionFunction::ResponseAction InputImeSendKeyEventsFunction::Run() { } InputImeAPI::InputImeAPI(content::BrowserContext* context) - : browser_context_(context), extension_registry_observer_(this) { + : browser_context_(context) { extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); EventRouter* event_router = EventRouter::Get(browser_context_); diff --git a/chromium/chrome/browser/extensions/api/input_ime/input_ime_api.h b/chromium/chrome/browser/extensions/api/input_ime/input_ime_api.h index c3fc3b3344e..30e838249f8 100644 --- a/chromium/chrome/browser/extensions/api/input_ime/input_ime_api.h +++ b/chromium/chrome/browser/extensions/api/input_ime/input_ime_api.h @@ -44,7 +44,7 @@ class ImeObserver : public input_method::InputMethodEngineBase::Observer { public: ImeObserver(const std::string& extension_id, Profile* profile); - ~ImeObserver() override {} + ~ImeObserver() override = default; // input_method::InputMethodEngineBase::Observer overrides. void OnActivate(const std::string& component_id) override; @@ -58,7 +58,6 @@ class ImeObserver : public input_method::InputMethodEngineBase::Observer { void OnDeactivated(const std::string& component_id) override; void OnCompositionBoundsChanged( const std::vector<gfx::Rect>& bounds) override; - bool IsInterestedInKeyEvent() const override; void OnSurroundingTextChanged(const std::string& component_id, const std::string& text, int cursor_pos, @@ -94,15 +93,17 @@ class ImeObserver : public input_method::InputMethodEngineBase::Observer { IMEEngineHandlerInterface::InputContext input_context); virtual bool ConvertInputContextAutoComplete( IMEEngineHandlerInterface::InputContext input_context); - virtual extensions::api::input_ime::AutoCapitalizeType - ConvertInputContextAutoCapitalize( - IMEEngineHandlerInterface::InputContext input_context); virtual bool ConvertInputContextSpellCheck( IMEEngineHandlerInterface::InputContext input_context); std::string extension_id_; Profile* profile_; + private: + extensions::api::input_ime::AutoCapitalizeType + ConvertInputContextAutoCapitalize( + IMEEngineHandlerInterface::InputContext input_context); + DISALLOW_COPY_AND_ASSIGN(ImeObserver); }; @@ -134,7 +135,7 @@ class InputImeKeyEventHandledFunction : public ExtensionFunction { INPUT_IME_KEYEVENTHANDLED) protected: - ~InputImeKeyEventHandledFunction() override {} + ~InputImeKeyEventHandledFunction() override = default; // ExtensionFunction: ResponseAction Run() override; @@ -146,7 +147,7 @@ class InputImeSetCompositionFunction : public ExtensionFunction { INPUT_IME_SETCOMPOSITION) protected: - ~InputImeSetCompositionFunction() override {} + ~InputImeSetCompositionFunction() override = default; // ExtensionFunction: ResponseAction Run() override; @@ -157,7 +158,7 @@ class InputImeCommitTextFunction : public ExtensionFunction { DECLARE_EXTENSION_FUNCTION("input.ime.commitText", INPUT_IME_COMMITTEXT) protected: - ~InputImeCommitTextFunction() override {} + ~InputImeCommitTextFunction() override = default; // ExtensionFunction: ResponseAction Run() override; @@ -168,7 +169,7 @@ class InputImeSendKeyEventsFunction : public ExtensionFunction { DECLARE_EXTENSION_FUNCTION("input.ime.sendKeyEvents", INPUT_IME_SENDKEYEVENTS) protected: - ~InputImeSendKeyEventsFunction() override {} + ~InputImeSendKeyEventsFunction() override = default; // ExtensionFunction: ResponseAction Run() override; @@ -216,7 +217,7 @@ class InputImeAPI : public BrowserContextKeyedAPI, // Listen to extension load, unloaded notifications. ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - extension_registry_observer_; + extension_registry_observer_{this}; content::NotificationRegistrar registrar_; diff --git a/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc b/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc index 697de915f2f..b8b1abc8c72 100644 --- a/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc +++ b/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc @@ -100,7 +100,7 @@ class ImeObserverChromeOS : public ui::ImeObserver { ImeObserverChromeOS(const std::string& extension_id, Profile* profile) : ImeObserver(extension_id, profile) {} - ~ImeObserverChromeOS() override {} + ~ImeObserverChromeOS() override = default; // input_method::InputMethodEngineBase::Observer overrides. void OnInputContextUpdate( @@ -191,12 +191,12 @@ class ImeObserverChromeOS : public ui::ImeObserver { // Note: this is a private API event. auto bounds_list = std::make_unique<base::ListValue>(); - for (size_t i = 0; i < bounds.size(); ++i) { + for (auto bound : bounds) { auto bounds_value = std::make_unique<base::DictionaryValue>(); - bounds_value->SetInteger("x", bounds[i].x()); - bounds_value->SetInteger("y", bounds[i].y()); - bounds_value->SetInteger("w", bounds[i].width()); - bounds_value->SetInteger("h", bounds[i].height()); + bounds_value->SetInteger("x", bound.x()); + bounds_value->SetInteger("y", bound.y()); + bounds_value->SetInteger("w", bound.width()); + bounds_value->SetInteger("h", bound.height()); bounds_list->Append(std::move(bounds_value)); } @@ -231,8 +231,8 @@ class ImeObserverChromeOS : public ui::ImeObserver { ConvertInputContextType(context)); input_context.auto_correct = ConvertInputContextAutoCorrect(context); input_context.auto_complete = ConvertInputContextAutoComplete(context); - input_context.auto_capitalize = (input_method_private::AutoCapitalizeType) - ConvertInputContextAutoCapitalize(context); + input_context.auto_capitalize = + ConvertInputContextAutoCapitalize(context.flags); input_context.spell_check = ConvertInputContextSpellCheck(context); input_context.has_been_password = ConvertHasBeenPassword(context); input_context.should_do_learning = context.should_do_learning; @@ -344,11 +344,22 @@ class ImeObserverChromeOS : public ui::ImeObserver { return ImeObserver::ConvertInputContextAutoComplete(input_context); } - input_ime::AutoCapitalizeType ConvertInputContextAutoCapitalize( - ui::IMEEngineHandlerInterface::InputContext input_context) override { + input_method_private::AutoCapitalizeType ConvertInputContextAutoCapitalize( + int flags) { if (!GetKeyboardConfig().auto_capitalize) - return input_ime::AUTO_CAPITALIZE_TYPE_NONE; - return ImeObserver::ConvertInputContextAutoCapitalize(input_context); + return input_method_private::AUTO_CAPITALIZE_TYPE_OFF; + if (flags & ui::TEXT_INPUT_FLAG_AUTOCAPITALIZE_NONE) + return input_method_private::AUTO_CAPITALIZE_TYPE_OFF; + if (flags & ui::TEXT_INPUT_FLAG_AUTOCAPITALIZE_CHARACTERS) + return input_method_private::AUTO_CAPITALIZE_TYPE_CHARACTERS; + if (flags & ui::TEXT_INPUT_FLAG_AUTOCAPITALIZE_WORDS) + return input_method_private::AUTO_CAPITALIZE_TYPE_WORDS; + if (flags & ui::TEXT_INPUT_FLAG_AUTOCAPITALIZE_SENTENCES) + return input_method_private::AUTO_CAPITALIZE_TYPE_SENTENCES; + + // Autocapitalize flag may be missing for native text fields. + // See https://crbug.com/1002713. + return input_method_private::AUTO_CAPITALIZE_TYPE_NONE; } bool ConvertInputContextSpellCheck( @@ -383,7 +394,7 @@ InputMethodEngine* GetEngineIfActive(Profile* profile, InputImeEventRouter::InputImeEventRouter(Profile* profile) : InputImeEventRouterBase(profile) {} -InputImeEventRouter::~InputImeEventRouter() {} +InputImeEventRouter::~InputImeEventRouter() = default; bool InputImeEventRouter::RegisterImeExtension( const std::string& extension_id, @@ -402,11 +413,7 @@ bool InputImeEventRouter::RegisterImeExtension( // Only creates descriptors for 3rd party IME extension, because the // descriptors for component IME extensions are managed by InputMethodUtil. if (!comp_ext_ime_manager->IsWhitelistedExtension(extension_id)) { - for (std::vector<InputComponentInfo>::const_iterator it = - input_components.begin(); - it != input_components.end(); - ++it) { - const InputComponentInfo& component = *it; + for (const auto& component : input_components) { DCHECK(component.type == INPUT_COMPONENT_TYPE_IME); std::vector<std::string> layouts; @@ -439,40 +446,37 @@ bool InputImeEventRouter::RegisterImeExtension( std::unique_ptr<InputMethodEngineBase::Observer> observer( new ImeObserverChromeOS(extension_id, profile)); - chromeos::InputMethodEngine* engine = new chromeos::InputMethodEngine(); + auto engine = std::make_unique<chromeos::InputMethodEngine>(); engine->Initialize(std::move(observer), extension_id.c_str(), profile); - engine_map_[extension_id] = engine; + engine_map_[extension_id] = std::move(engine); chromeos::UserSessionManager::GetInstance() ->GetDefaultIMEState(profile) - ->AddInputMethodExtension(extension_id, descriptors, engine); + ->AddInputMethodExtension(extension_id, descriptors, + engine_map_[extension_id].get()); return true; } void InputImeEventRouter::UnregisterAllImes(const std::string& extension_id) { - std::map<std::string, InputMethodEngine*>::iterator it = - engine_map_.find(extension_id); + auto it = engine_map_.find(extension_id); if (it != engine_map_.end()) { chromeos::input_method::InputMethodManager::Get() ->GetActiveIMEState() ->RemoveInputMethodExtension(extension_id); - delete it->second; engine_map_.erase(it); } } InputMethodEngine* InputImeEventRouter::GetEngine( const std::string& extension_id) { - std::map<std::string, InputMethodEngine*>::iterator it = - engine_map_.find(extension_id); - return (it != engine_map_.end()) ? it->second : nullptr; + auto it = engine_map_.find(extension_id); + return (it != engine_map_.end()) ? it->second.get() : nullptr; } InputMethodEngineBase* InputImeEventRouter::GetEngineIfActive( const std::string& extension_id) { - std::map<std::string, InputMethodEngine*>::iterator it = - engine_map_.find(extension_id); - return (it != engine_map_.end() && it->second->IsActive()) ? it->second + auto it = engine_map_.find(extension_id); + return (it != engine_map_.end() && it->second->IsActive()) ? it->second.get() : nullptr; } @@ -592,7 +596,7 @@ ExtensionFunction::ResponseAction InputImeSetCandidatesFunction::Run() { std::vector<InputMethodEngine::Candidate> candidates_out; for (const auto& candidate_in : params.candidates) { - candidates_out.push_back(InputMethodEngine::Candidate()); + candidates_out.emplace_back(); candidates_out.back().value = candidate_in.candidate; candidates_out.back().id = candidate_in.id; if (candidate_in.label) @@ -652,7 +656,7 @@ ExtensionFunction::ResponseAction InputImeSetMenuItemsFunction::Run() { std::vector<chromeos::input_method::InputMethodManager::MenuItem> items_out; for (const input_ime::MenuItem& item_in : params.items) { - items_out.push_back(chromeos::input_method::InputMethodManager::MenuItem()); + items_out.emplace_back(); SetMenuItemToMenu(item_in, &items_out.back()); } @@ -676,7 +680,7 @@ ExtensionFunction::ResponseAction InputImeUpdateMenuItemsFunction::Run() { std::vector<chromeos::input_method::InputMethodManager::MenuItem> items_out; for (const input_ime::MenuItem& item_in : params.items) { - items_out.push_back(chromeos::input_method::InputMethodManager::MenuItem()); + items_out.emplace_back(); SetMenuItemToMenu(item_in, &items_out.back()); } diff --git a/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.h b/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.h index c07e7259450..12a8e0098a0 100644 --- a/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.h +++ b/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.h @@ -27,7 +27,7 @@ class InputImeClearCompositionFunction : public ExtensionFunction { INPUT_IME_CLEARCOMPOSITION) protected: - ~InputImeClearCompositionFunction() override {} + ~InputImeClearCompositionFunction() override = default; // ExtensionFunction: ResponseAction Run() override; @@ -39,7 +39,7 @@ class InputImeSetCandidateWindowPropertiesFunction : public ExtensionFunction { INPUT_IME_SETCANDIDATEWINDOWPROPERTIES) protected: - ~InputImeSetCandidateWindowPropertiesFunction() override {} + ~InputImeSetCandidateWindowPropertiesFunction() override = default; // ExtensionFunction: ResponseAction Run() override; @@ -50,7 +50,7 @@ class InputImeSetCandidatesFunction : public ExtensionFunction { DECLARE_EXTENSION_FUNCTION("input.ime.setCandidates", INPUT_IME_SETCANDIDATES) protected: - ~InputImeSetCandidatesFunction() override {} + ~InputImeSetCandidatesFunction() override = default; // ExtensionFunction: ResponseAction Run() override; @@ -62,7 +62,7 @@ class InputImeSetCursorPositionFunction : public ExtensionFunction { INPUT_IME_SETCURSORPOSITION) protected: - ~InputImeSetCursorPositionFunction() override {} + ~InputImeSetCursorPositionFunction() override = default; // ExtensionFunction: ResponseAction Run() override; @@ -73,7 +73,7 @@ class InputImeSetMenuItemsFunction : public ExtensionFunction { DECLARE_EXTENSION_FUNCTION("input.ime.setMenuItems", INPUT_IME_SETMENUITEMS) protected: - ~InputImeSetMenuItemsFunction() override {} + ~InputImeSetMenuItemsFunction() override = default; // ExtensionFunction: ResponseAction Run() override; @@ -85,7 +85,7 @@ class InputImeUpdateMenuItemsFunction : public ExtensionFunction { INPUT_IME_UPDATEMENUITEMS) protected: - ~InputImeUpdateMenuItemsFunction() override {} + ~InputImeUpdateMenuItemsFunction() override = default; // ExtensionFunction: ResponseAction Run() override; @@ -96,7 +96,7 @@ class InputImeDeleteSurroundingTextFunction : public ExtensionFunction { DECLARE_EXTENSION_FUNCTION("input.ime.deleteSurroundingText", INPUT_IME_DELETESURROUNDINGTEXT) protected: - ~InputImeDeleteSurroundingTextFunction() override {} + ~InputImeDeleteSurroundingTextFunction() override = default; // ExtensionFunction: ResponseAction Run() override; @@ -108,7 +108,7 @@ class InputImeHideInputViewFunction : public ExtensionFunction { INPUT_IME_HIDEINPUTVIEW) protected: - ~InputImeHideInputViewFunction() override {} + ~InputImeHideInputViewFunction() override = default; // ExtensionFunction: ResponseAction Run() override; @@ -117,10 +117,10 @@ class InputImeHideInputViewFunction : public ExtensionFunction { class InputMethodPrivateNotifyImeMenuItemActivatedFunction : public ExtensionFunction { public: - InputMethodPrivateNotifyImeMenuItemActivatedFunction() {} + InputMethodPrivateNotifyImeMenuItemActivatedFunction() = default; protected: - ~InputMethodPrivateNotifyImeMenuItemActivatedFunction() override {} + ~InputMethodPrivateNotifyImeMenuItemActivatedFunction() override = default; // ExtensionFunction: ResponseAction Run() override; @@ -139,7 +139,7 @@ class InputMethodPrivateGetCompositionBoundsFunction INPUTMETHODPRIVATE_GETCOMPOSITIONBOUNDS) protected: - ~InputMethodPrivateGetCompositionBoundsFunction() override {} + ~InputMethodPrivateGetCompositionBoundsFunction() override = default; // ExtensionFunction: ResponseAction Run() override; @@ -169,7 +169,8 @@ class InputImeEventRouter : public InputImeEventRouterBase { private: // The engine map from extension_id to an engine. - std::map<std::string, chromeos::InputMethodEngine*> engine_map_; + std::map<std::string, std::unique_ptr<chromeos::InputMethodEngine>> + engine_map_; // The first party ime extension which is unloaded unexpectedly. std::string unloaded_component_extension_id_; diff --git a/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc b/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc index 95a52f9e403..37db426539d 100644 --- a/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc +++ b/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc @@ -75,7 +75,7 @@ class ImeObserverNonChromeOS : public ui::ImeObserver { ImeObserverNonChromeOS(const std::string& extension_id, Profile* profile) : ImeObserver(extension_id, profile) {} - ~ImeObserverNonChromeOS() override {} + ~ImeObserverNonChromeOS() override = default; void OnCompositionBoundsChanged( const std::vector<gfx::Rect>& bounds) override { diff --git a/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.h b/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.h index 68e06c59d6a..e4f3fac9729 100644 --- a/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.h +++ b/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.h @@ -60,7 +60,7 @@ class InputImeCreateWindowFunction : public ExtensionFunction { DECLARE_EXTENSION_FUNCTION("input.ime.createWindow", INPUT_IME_CREATEWINDOW) protected: - ~InputImeCreateWindowFunction() override {} + ~InputImeCreateWindowFunction() override = default; // ExtensionFunction: ExtensionFunction::ResponseAction Run() override; @@ -71,7 +71,7 @@ class InputImeShowWindowFunction : public ExtensionFunction { DECLARE_EXTENSION_FUNCTION("input.ime.showWindow", INPUT_IME_SHOWWINDOW) protected: - ~InputImeShowWindowFunction() override {} + ~InputImeShowWindowFunction() override = default; // ExtensionFunction: ExtensionFunction::ResponseAction Run() override; @@ -82,7 +82,7 @@ class InputImeHideWindowFunction : public ExtensionFunction { DECLARE_EXTENSION_FUNCTION("input.ime.hideWindow", INPUT_IME_HIDEWINDOW) protected: - ~InputImeHideWindowFunction() override {} + ~InputImeHideWindowFunction() override = default; // ExtensionFunction: ExtensionFunction::ResponseAction Run() override; @@ -97,7 +97,7 @@ class InputImeActivateFunction : public ExtensionFunction { static bool disable_bubble_for_testing_; protected: - ~InputImeActivateFunction() override {} + ~InputImeActivateFunction() override = default; // ExtensionFunction: ResponseAction Run() override; @@ -114,7 +114,7 @@ class InputImeDeactivateFunction : public ExtensionFunction { DECLARE_EXTENSION_FUNCTION("input.ime.deactivate", INPUT_IME_DEACTIVATE) protected: - ~InputImeDeactivateFunction() override {} + ~InputImeDeactivateFunction() override = default; // ExtensionFunction: ResponseAction Run() override; diff --git a/chromium/chrome/browser/extensions/api/input_ime/input_ime_event_router_base.cc b/chromium/chrome/browser/extensions/api/input_ime/input_ime_event_router_base.cc index 5fba14ccace..0fc721fb9c9 100644 --- a/chromium/chrome/browser/extensions/api/input_ime/input_ime_event_router_base.cc +++ b/chromium/chrome/browser/extensions/api/input_ime/input_ime_event_router_base.cc @@ -11,6 +11,6 @@ namespace extensions { InputImeEventRouterBase::InputImeEventRouterBase(Profile* profile) : profile_(profile) {} -InputImeEventRouterBase::~InputImeEventRouterBase() {} +InputImeEventRouterBase::~InputImeEventRouterBase() = default; } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc b/chromium/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc index 3e82ec740d5..50f513b5075 100644 --- a/chromium/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc +++ b/chromium/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc @@ -91,7 +91,7 @@ std::unordered_set<std::string> GetIMEsFromPref(PrefService* prefs, // Returns the set of allowed UI locales. std::unordered_set<std::string> GetAllowedLanguages(PrefService* prefs) { std::unordered_set<std::string> allowed_languages; - const base::Value::ListStorage& pref_value = + base::span<const base::Value> pref_value = prefs->GetList(prefs::kAllowedLanguages)->GetList(); for (const base::Value& locale_value : pref_value) allowed_languages.insert(locale_value.GetString()); diff --git a/chromium/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc b/chromium/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc index 9dd95841737..a1b11bc2c1a 100644 --- a/chromium/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc +++ b/chromium/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc @@ -227,7 +227,7 @@ class ChromeAppForLinkDelegate : public extensions::AppForLinkDelegate { web_app_info->open_as_window = false; if (!image_result.image.IsEmpty()) { - WebApplicationInfo::IconInfo icon; + WebApplicationIconInfo icon; icon.data = image_result.image.AsBitmap(); icon.width = icon.data.width(); icon.height = icon.data.height(); @@ -305,10 +305,10 @@ void ChromeManagementAPIDelegate::LaunchAppFunctionDelegate( extensions::LaunchContainer launch_container = GetLaunchContainer(extensions::ExtensionPrefs::Get(context), extension); Profile* profile = Profile::FromBrowserContext(context); - apps::LaunchService::Get(profile)->OpenApplication( - AppLaunchParams(profile, extension->id(), launch_container, - WindowOpenDisposition::NEW_FOREGROUND_TAB, - apps::mojom::AppLaunchSource::kSourceManagementApi)); + apps::LaunchService::Get(profile)->OpenApplication(apps::AppLaunchParams( + extension->id(), launch_container, + WindowOpenDisposition::NEW_FOREGROUND_TAB, + apps::mojom::AppLaunchSource::kSourceManagementApi)); #if defined(OS_CHROMEOS) chromeos::DemoSession::RecordAppLaunchSourceIfInDemoMode( diff --git a/chromium/chrome/browser/extensions/api/management/management_api_browsertest.cc b/chromium/chrome/browser/extensions/api/management/management_api_browsertest.cc index 93f3c8d8979..64291f90770 100644 --- a/chromium/chrome/browser/extensions/api/management/management_api_browsertest.cc +++ b/chromium/chrome/browser/extensions/api/management/management_api_browsertest.cc @@ -245,15 +245,12 @@ class ExtensionManagementApiEscalationTest : // Install low-permission version of the extension. ASSERT_TRUE(InstallExtension(path_v1, 1)); - EXPECT_TRUE(extension_registry()->GetExtensionById( - kId, ExtensionRegistry::ENABLED)); + EXPECT_TRUE(extension_registry()->enabled_extensions().GetByID(kId)); // Update to a high-permission version - it should get disabled. EXPECT_FALSE(UpdateExtension(kId, path_v2, -1)); - EXPECT_FALSE(extension_registry()->GetExtensionById( - kId, ExtensionRegistry::ENABLED)); - EXPECT_TRUE(extension_registry()->GetExtensionById( - kId, ExtensionRegistry::COMPATIBILITY)); + EXPECT_FALSE(extension_registry()->enabled_extensions().GetByID(kId)); + EXPECT_TRUE(extension_registry()->disabled_extensions().GetByID(kId)); EXPECT_TRUE(ExtensionPrefs::Get(browser()->profile()) ->DidExtensionEscalatePermissions(kId)); } @@ -347,9 +344,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementApiEscalationTest, extension_service()->AddExtension(target_extension.get()); SetEnabled(false, true, std::string(), source_extension); SetEnabled(true, true, std::string(), source_extension); - const Extension* extension = - extension_registry()->GetExtensionById(kId, ExtensionRegistry::ENABLED); - EXPECT_TRUE(extension); + EXPECT_TRUE(extension_registry()->enabled_extensions().GetByID(kId)); } } diff --git a/chromium/chrome/browser/extensions/api/management/management_api_non_persistent_apitest.cc b/chromium/chrome/browser/extensions/api/management/management_api_non_persistent_apitest.cc index febd21f6435..3d664ad345b 100644 --- a/chromium/chrome/browser/extensions/api/management/management_api_non_persistent_apitest.cc +++ b/chromium/chrome/browser/extensions/api/management/management_api_non_persistent_apitest.cc @@ -121,8 +121,9 @@ INSTANTIATE_TEST_SUITE_P(EventPage, ManagementApiNonPersistentApiTest, ::testing::Values(ContextType::kEventPage)); -INSTANTIATE_TEST_SUITE_P(ServiceWorker, - ManagementApiNonPersistentApiTest, - ::testing::Values(ContextType::kServiceWorker)); +// Flaky: crbug.com/1003597 +// INSTANTIATE_TEST_SUITE_P(ServiceWorker, +// ManagementApiNonPersistentApiTest, +// ::testing::Values(ContextType::kServiceWorker)); } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/management/management_api_unittest.cc b/chromium/chrome/browser/extensions/api/management/management_api_unittest.cc index 5f753cc87b3..badfd1880a9 100644 --- a/chromium/chrome/browser/extensions/api/management/management_api_unittest.cc +++ b/chromium/chrome/browser/extensions/api/management/management_api_unittest.cc @@ -549,6 +549,53 @@ TEST_F(ManagementApiUnitTest, ExtensionInfo_MayEnable) { } } +TEST_F(ManagementApiUnitTest, ExtensionInfo_MayDisable) { + using ExtensionInfo = api::management::ExtensionInfo; + + scoped_refptr<const Extension> extension = ExtensionBuilder("Test").Build(); + service()->AddExtension(extension.get()); + + const std::string args = + base::StringPrintf("[\"%s\"]", extension->id().c_str()); + + // Initially the extension should show as enabled, so it may be disabled + // freely. + EXPECT_TRUE(registry()->enabled_extensions().Contains(extension->id())); + { + scoped_refptr<ExtensionFunction> function = new ManagementGetFunction(); + std::unique_ptr<base::Value> value( + extension_function_test_utils::RunFunctionAndReturnSingleResult( + function.get(), args, browser())); + ASSERT_TRUE(value); + std::unique_ptr<ExtensionInfo> info = ExtensionInfo::FromValue(*value); + ASSERT_TRUE(info); + EXPECT_TRUE(info->enabled); + EXPECT_TRUE(info->may_disable); + } + + // Simulate forcing the extension and verify that the extension shows with + // a false value of |may_disable|. + ManagementPolicy* policy = + ExtensionSystem::Get(profile())->management_policy(); + policy->UnregisterAllProviders(); + TestManagementPolicyProvider provider( + TestManagementPolicyProvider::MUST_REMAIN_ENABLED); + policy->RegisterProvider(&provider); + service()->CheckManagementPolicy(); + EXPECT_TRUE(registry()->enabled_extensions().Contains(extension->id())); + { + scoped_refptr<ExtensionFunction> function = new ManagementGetFunction(); + std::unique_ptr<base::Value> value( + extension_function_test_utils::RunFunctionAndReturnSingleResult( + function.get(), args, browser())); + ASSERT_TRUE(value); + std::unique_ptr<ExtensionInfo> info = ExtensionInfo::FromValue(*value); + ASSERT_TRUE(info); + EXPECT_TRUE(info->enabled); + EXPECT_FALSE(info->may_disable); + } +} + // Tests enabling an extension via management API after it was disabled due to // permission increase. TEST_F(ManagementApiUnitTest, SetEnabledAfterIncreasedPermissions) { diff --git a/chromium/chrome/browser/extensions/api/management/management_apitest.cc b/chromium/chrome/browser/extensions/api/management/management_apitest.cc index bbc3cb9f617..89973e38806 100644 --- a/chromium/chrome/browser/extensions/api/management/management_apitest.cc +++ b/chromium/chrome/browser/extensions/api/management/management_apitest.cc @@ -340,9 +340,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, extensions::ScopedTestDialogAutoConfirm::ACCEPT); extensions::ExtensionRegistry* registry = extensions::ExtensionRegistry::Get(browser()->profile()); - EXPECT_TRUE( - registry->GetExtensionById(extension_ids_["enabled_extension"], - extensions::ExtensionRegistry::ENABLED)); + EXPECT_TRUE(registry->enabled_extensions().GetByID( + extension_ids_["enabled_extension"])); // Ensure that all actions are allowed. extensions::ExtensionSystem::Get( @@ -353,7 +352,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, // The last thing the test does is uninstall the "enabled_extension". EXPECT_FALSE( registry->GetExtensionById(extension_ids_["enabled_extension"], - extensions::ExtensionRegistry::COMPATIBILITY)); + extensions::ExtensionRegistry::EVERYTHING)); } // Fails often on Windows dbg bots. http://crbug.com/177163 @@ -368,16 +367,17 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, LoadExtensions(); extensions::ExtensionRegistry* registry = extensions::ExtensionRegistry::Get(browser()->profile()); - EXPECT_TRUE( - registry->GetExtensionById(extension_ids_["enabled_extension"], - extensions::ExtensionRegistry::ENABLED)); + EXPECT_TRUE(registry->enabled_extensions().GetByID( + extension_ids_["enabled_extension"])); // Prohibit status changes. extensions::ManagementPolicy* policy = extensions::ExtensionSystem::Get( browser()->profile())->management_policy(); policy->UnregisterAllProviders(); extensions::TestManagementPolicyProvider provider( - extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS); + extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS | + extensions::TestManagementPolicyProvider::MUST_REMAIN_ENABLED | + extensions::TestManagementPolicyProvider::MUST_REMAIN_INSTALLED); policy->RegisterProvider(&provider); ASSERT_TRUE(RunExtensionSubtest("management/management_policy", "prohibited.html")); @@ -410,7 +410,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, LaunchPanelApp) { UninstallExtension(app_id); ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile())); ASSERT_FALSE(registry->GetExtensionById( - app_id, extensions::ExtensionRegistry::COMPATIBILITY)); + app_id, extensions::ExtensionRegistry::EVERYTHING)); // Set a pref indicating that the user wants to launch in a regular tab. // This should be ignored, because panel apps always load in a popup. @@ -468,7 +468,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, MAYBE_LaunchTabApp) { UninstallExtension(app_id); ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile())); ASSERT_FALSE(registry->GetExtensionById( - app_id, extensions::ExtensionRegistry::COMPATIBILITY)); + app_id, extensions::ExtensionRegistry::EVERYTHING)); // Set a pref indicating that the user wants to launch in a window. extensions::SetLaunchType(browser()->profile(), app_id, diff --git a/chromium/chrome/browser/extensions/api/management/management_browsertest.cc b/chromium/chrome/browser/extensions/api/management/management_browsertest.cc index 91b2e2ceb0a..265e4a24847 100644 --- a/chromium/chrome/browser/extensions/api/management/management_browsertest.cc +++ b/chromium/chrome/browser/extensions/api/management/management_browsertest.cc @@ -261,8 +261,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_InstallRequiresConfirm) { // it being disabled, since good.crx has permissions that require approval. std::string id = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; ASSERT_FALSE(InstallExtension(test_data_dir_.AppendASCII("good.crx"), 0)); - ASSERT_TRUE(extension_registry()->GetExtensionById( - id, ExtensionRegistry::COMPATIBILITY)); + ASSERT_TRUE(extension_registry()->disabled_extensions().GetByID(id)); UninstallExtension(id); // And the install should succeed when the permissions are accepted. @@ -445,8 +444,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_AutoUpdate) { install_observer.WaitForExtensionWillBeInstalled(); EXPECT_TRUE(listener2.WaitUntilSatisfied()); ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); - extension = registry->GetExtensionById("ogjcoiohnmldgjemafoockdghcjciccf", - ExtensionRegistry::ENABLED); + extension = registry->enabled_extensions().GetByID( + "ogjcoiohnmldgjemafoockdghcjciccf"); ASSERT_TRUE(extension); ASSERT_EQ("2.0", extension->VersionString()); ASSERT_TRUE(notification_listener.started()); @@ -470,8 +469,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_AutoUpdate) { // Make sure the extension state is the same as before. ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); - extension = registry->GetExtensionById("ogjcoiohnmldgjemafoockdghcjciccf", - ExtensionRegistry::ENABLED); + extension = registry->enabled_extensions().GetByID( + "ogjcoiohnmldgjemafoockdghcjciccf"); ASSERT_TRUE(extension); ASSERT_EQ("2.0", extension->VersionString()); } @@ -546,11 +545,11 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, install_observer.WaitForExtensionWillBeInstalled(); ASSERT_EQ(disabled_size_before + 1, registry->disabled_extensions().size()); ASSERT_EQ(enabled_size_before, registry->enabled_extensions().size()); - extension = registry->GetExtensionById("ogjcoiohnmldgjemafoockdghcjciccf", - ExtensionRegistry::COMPATIBILITY); + extension = registry->disabled_extensions().GetByID( + "ogjcoiohnmldgjemafoockdghcjciccf"); ASSERT_TRUE(extension); - ASSERT_FALSE(registry->GetExtensionById("ogjcoiohnmldgjemafoockdghcjciccf", - ExtensionRegistry::ENABLED)); + ASSERT_FALSE(registry->enabled_extensions().GetByID( + "ogjcoiohnmldgjemafoockdghcjciccf")); ASSERT_EQ("2.0", extension->VersionString()); // The extension should have not made the callback because it is disabled. @@ -621,7 +620,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalUrlUpdate) { install_observer.WaitForExtensionWillBeInstalled(); ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); const Extension* extension = - registry->GetExtensionById(kExtensionId, ExtensionRegistry::ENABLED); + registry->enabled_extensions().GetByID(kExtensionId); ASSERT_TRUE(extension); ASSERT_EQ("2.0", extension->VersionString()); @@ -726,7 +725,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalPolicyRefresh) { // Check if the extension got installed. ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); const Extension* extension = - registry->GetExtensionById(kExtensionId, ExtensionRegistry::ENABLED); + registry->enabled_extensions().GetByID(kExtensionId); ASSERT_TRUE(extension); ASSERT_EQ("2.0", extension->VersionString()); EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location()); @@ -751,8 +750,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalPolicyRefresh) { policies.Erase(policy::key::kExtensionInstallForcelist); UpdateProviderPolicy(policies); EXPECT_EQ(size_before + 1, registry->enabled_extensions().size()); - EXPECT_FALSE(registry->GetExtensionById(kExtensionId, - ExtensionRegistry::COMPATIBILITY)); + EXPECT_FALSE( + registry->GetExtensionById(kExtensionId, ExtensionRegistry::EVERYTHING)); } // See http://crbug.com/103371 and http://crbug.com/120640. @@ -808,7 +807,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ASSERT_TRUE(InstallExtension(v2_path, 1)); ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); const Extension* extension = - registry->GetExtensionById(kExtensionId, ExtensionRegistry::ENABLED); + registry->enabled_extensions().GetByID(kExtensionId); ASSERT_TRUE(extension); EXPECT_EQ(Manifest::INTERNAL, extension->location()); EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId)); @@ -827,8 +826,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, install_observer.WaitForExtensionWillBeInstalled(); ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); - extension = - registry->GetExtensionById(kExtensionId, ExtensionRegistry::ENABLED); + extension = registry->enabled_extensions().GetByID(kExtensionId); ASSERT_TRUE(extension); EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location()); EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId)); @@ -840,15 +838,14 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, policies.Erase(policy::key::kExtensionInstallForcelist); UpdateProviderPolicy(policies); ASSERT_EQ(size_before, registry->enabled_extensions().size()); - extension = registry->GetExtensionById(kExtensionId, - ExtensionRegistry::COMPATIBILITY); + extension = + registry->GetExtensionById(kExtensionId, ExtensionRegistry::EVERYTHING); EXPECT_FALSE(extension); // User install again, but have it disabled too before setting the policy. ASSERT_TRUE(InstallExtension(v2_path, 1)); ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); - extension = - registry->GetExtensionById(kExtensionId, ExtensionRegistry::ENABLED); + extension = registry->enabled_extensions().GetByID(kExtensionId); ASSERT_TRUE(extension); EXPECT_EQ(Manifest::INTERNAL, extension->location()); EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId)); @@ -856,8 +853,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, DisableExtension(kExtensionId); EXPECT_EQ(1u, registry->disabled_extensions().size()); - extension = registry->GetExtensionById(kExtensionId, - ExtensionRegistry::COMPATIBILITY); + extension = registry->disabled_extensions().GetByID(kExtensionId); EXPECT_TRUE(extension); EXPECT_FALSE(service->IsExtensionEnabled(kExtensionId)); @@ -873,8 +869,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, extension_observer.WaitForExtensionWillBeInstalled(); ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); - extension = - registry->GetExtensionById(kExtensionId, ExtensionRegistry::ENABLED); + extension = registry->enabled_extensions().GetByID(kExtensionId); ASSERT_TRUE(extension); EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location()); EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId)); diff --git a/chromium/chrome/browser/extensions/api/media_perception_private/media_perception_api_delegate_chromeos.cc b/chromium/chrome/browser/extensions/api/media_perception_private/media_perception_api_delegate_chromeos.cc index 69ddd3fbc6a..70f0710c4cf 100644 --- a/chromium/chrome/browser/extensions/api/media_perception_private/media_perception_api_delegate_chromeos.cc +++ b/chromium/chrome/browser/extensions/api/media_perception_private/media_perception_api_delegate_chromeos.cc @@ -9,6 +9,7 @@ #include "base/bind.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/component_updater/cros_component_installer_chromeos.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/chromeos/delegate_to_browser_gpu_service_accelerator_factory.h" diff --git a/chromium/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.cc b/chromium/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.cc index ff4cc1c31a6..a236b6b0709 100644 --- a/chromium/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.cc +++ b/chromium/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.cc @@ -86,8 +86,13 @@ std::unique_ptr<base::DictionaryValue> ChromeMessagingDelegate::MaybeGetTabInfo( // reached as a result of a tab (or content script) messaging the extension. // We need the extension to see the sender so that it can validate if it // trusts it or not. - return ExtensionTabUtil::CreateTabObject( - web_contents, ExtensionTabUtil::kDontScrubTab, nullptr) + // TODO(tjudkins): Adjust scrubbing behavior in this situation to not scrub + // the last committed URL, but do scrub the pending URL based on + // permissions. + ExtensionTabUtil::ScrubTabBehavior scrub_tab_behavior = { + ExtensionTabUtil::kDontScrubTab, ExtensionTabUtil::kDontScrubTab}; + return ExtensionTabUtil::CreateTabObject(web_contents, scrub_tab_behavior, + nullptr) ->ToValue(); } return nullptr; diff --git a/chromium/chrome/browser/extensions/api/messaging/native_messaging_apitest.cc b/chromium/chrome/browser/extensions/api/messaging/native_messaging_apitest.cc index 33042b32456..3e6af3e0cc7 100644 --- a/chromium/chrome/browser/extensions/api/messaging/native_messaging_apitest.cc +++ b/chromium/chrome/browser/extensions/api/messaging/native_messaging_apitest.cc @@ -33,7 +33,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, UserLevelNativeMessaging) { class TestProcessManagerObserver : public ProcessManagerObserver { public: - TestProcessManagerObserver() : observer_(this) {} + TestProcessManagerObserver() = default; + ~TestProcessManagerObserver() override = default; void WaitForProcessShutdown(ProcessManager* process_manager, const std::string& extension_id) { @@ -57,21 +58,29 @@ class TestProcessManagerObserver : public ProcessManagerObserver { } std::string extension_id_; - ScopedObserver<ProcessManager, TestProcessManagerObserver> observer_; + ScopedObserver<ProcessManager, ProcessManagerObserver> observer_{this}; base::OnceClosure quit_; DISALLOW_COPY_AND_ASSIGN(TestProcessManagerObserver); }; +class NativeMessagingApiTest : public ExtensionApiTest { + public: + NativeMessagingApiTest() { + feature_list_.InitAndEnableFeature(features::kOnConnectNative); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + // Disabled on Windows due to timeouts; see https://crbug.com/984897. #if defined(OS_WIN) #define MAYBE_NativeMessagingLaunch DISABLED_NativeMessagingLaunch #else #define MAYBE_NativeMessagingLaunch NativeMessagingLaunch #endif -IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_NativeMessagingLaunch) { - base::test::ScopedFeatureList features; - features.InitAndEnableFeature(features::kOnConnectNative); +IN_PROC_BROWSER_TEST_F(NativeMessagingApiTest, MAYBE_NativeMessagingLaunch) { ProcessManager::SetEventPageIdleTimeForTesting(1); ProcessManager::SetEventPageSuspendingTimeForTesting(1); extensions::ScopedTestNativeMessagingHost test_host; @@ -112,10 +121,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_NativeMessagingLaunch) { // natively-initiated connections is not allowed. The test extension expects the // channel to be immediately closed with an error. IN_PROC_BROWSER_TEST_F( - ExtensionApiTest, + NativeMessagingApiTest, NativeMessagingLaunch_LaunchFromNativeUnsupportedByNativeHost) { - base::test::ScopedFeatureList features; - features.InitAndEnableFeature(features::kOnConnectNative); ProcessManager::SetEventPageIdleTimeForTesting(1); ProcessManager::SetEventPageSuspendingTimeForTesting(1); extensions::ScopedTestNativeMessagingHost test_host; diff --git a/chromium/chrome/browser/extensions/api/messaging/native_process_launcher.cc b/chromium/chrome/browser/extensions/api/messaging/native_process_launcher.cc index edfdcbf0bc5..e8480b47786 100644 --- a/chromium/chrome/browser/extensions/api/messaging/native_process_launcher.cc +++ b/chromium/chrome/browser/extensions/api/messaging/native_process_launcher.cc @@ -258,7 +258,7 @@ void NativeProcessLauncherImpl::Core::DoLaunchOnThreadPool( base::Value args(base::Value::Type::LIST); args.GetList().reserve(reconnect_command_line.argv().size()); for (const auto& arg : reconnect_command_line.argv()) { - args.GetList().emplace_back(arg); + args.Append(arg); } std::string encoded_reconnect_command; bool success = diff --git a/chromium/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc b/chromium/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc index bedfe826489..282c0c96f0f 100644 --- a/chromium/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc +++ b/chromium/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc @@ -39,12 +39,18 @@ #include "chromeos/network/onc/onc_utils.h" #include "chromeos/network/portal_detector/network_portal_detector.h" #include "components/onc/onc_constants.h" +#include "components/onc/onc_pref_names.h" #include "components/policy/core/browser/browser_policy_connector.h" #include "components/policy/core/common/external_data_fetcher.h" #include "components/policy/core/common/mock_configuration_policy_provider.h" #include "components/policy/core/common/policy_map.h" #include "components/policy/core/common/policy_types.h" #include "components/policy/policy_constants.h" +#include "components/prefs/testing_pref_service.h" +#include "components/proxy_config/pref_proxy_config_tracker_impl.h" +#include "components/proxy_config/proxy_config_dictionary.h" +#include "components/proxy_config/proxy_config_pref_names.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" #include "components/user_manager/user.h" #include "components/user_manager/user_manager.h" #include "components/user_manager/user_names.h" @@ -465,6 +471,13 @@ class NetworkingPrivateChromeOSApiTest : public extensions::ExtensionApiTest { base::Value("third_party_provider_extension_id")); profile_test_->AddService(kUser1ProfilePath, "stub_vpn2"); + PrefProxyConfigTrackerImpl::RegisterProfilePrefs(user_prefs_.registry()); + PrefProxyConfigTrackerImpl::RegisterPrefs(local_state_.registry()); + ::onc::RegisterProfilePrefs(user_prefs_.registry()); + ::onc::RegisterPrefs(local_state_.registry()); + + chromeos::NetworkHandler::Get()->InitializePrefServices(&user_prefs_, + &local_state_); content::RunAllPendingInMessageLoop(); } @@ -487,6 +500,8 @@ class NetworkingPrivateChromeOSApiTest : public extensions::ExtensionApiTest { ShillServiceClient::TestInterface* service_test_; ShillDeviceClient::TestInterface* device_test_; policy::MockConfigurationPolicyProvider provider_; + sync_preferences::TestingPrefServiceSyncable user_prefs_; + TestingPrefServiceSimple local_state_; std::string userhash_; private: @@ -550,10 +565,9 @@ IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest, EXPECT_TRUE(RunNetworkingSubtest("getVisibleNetworksWifi")) << message_; } -// TODO(crbug.com/928778): Flaky on CrOS. -IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest, - DISABLED_EnabledNetworkTypes) { - EXPECT_TRUE(RunNetworkingSubtest("enabledNetworkTypes")) << message_; +IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest, EnabledNetworkTypes) { + EXPECT_TRUE(RunNetworkingSubtest("enabledNetworkTypesDisable")) << message_; + EXPECT_TRUE(RunNetworkingSubtest("enabledNetworkTypesEnable")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest, GetDeviceStates) { @@ -722,6 +736,9 @@ IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest, GetManagedProperties) { { "GUID": "stub_wifi2", "Type": "WiFi", "Name": "My WiFi Network", + "ProxySettings":{ + "Type": "Direct" + }, "WiFi": { "HexSSID": "77696669325F50534B", "Passphrase": "passphrase", diff --git a/chromium/chrome/browser/extensions/api/notifications/notifications_apitest.cc b/chromium/chrome/browser/extensions/api/notifications/notifications_apitest.cc index 427be63bed1..3c64e1f58d2 100644 --- a/chromium/chrome/browser/extensions/api/notifications/notifications_apitest.cc +++ b/chromium/chrome/browser/extensions/api/notifications/notifications_apitest.cc @@ -206,11 +206,10 @@ class NotificationsApiTest : public extensions::ExtensionApiTest { void LaunchPlatformApp(const Extension* extension) { apps::LaunchService::Get(browser()->profile()) - ->OpenApplication( - AppLaunchParams(browser()->profile(), extension->id(), - apps::mojom::LaunchContainer::kLaunchContainerNone, - WindowOpenDisposition::NEW_WINDOW, - apps::mojom::AppLaunchSource::kSourceTest)); + ->OpenApplication(apps::AppLaunchParams( + extension->id(), apps::mojom::LaunchContainer::kLaunchContainerNone, + WindowOpenDisposition::NEW_WINDOW, + apps::mojom::AppLaunchSource::kSourceTest)); } std::unique_ptr<NotificationDisplayServiceTester> display_service_tester_; diff --git a/chromium/chrome/browser/extensions/api/omnibox/omnibox_api.cc b/chromium/chrome/browser/extensions/api/omnibox/omnibox_api.cc index 7438cd81785..25f06908256 100644 --- a/chromium/chrome/browser/extensions/api/omnibox/omnibox_api.cc +++ b/chromium/chrome/browser/extensions/api/omnibox/omnibox_api.cc @@ -26,7 +26,6 @@ #include "extensions/browser/event_router.h" #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_prefs_factory.h" -#include "extensions/browser/extension_registry.h" #include "extensions/browser/notification_types.h" #include "ui/gfx/image/image.h" @@ -187,8 +186,7 @@ void ExtensionOmniboxEventRouter::OnDeleteSuggestion( OmniboxAPI::OmniboxAPI(content::BrowserContext* context) : profile_(Profile::FromBrowserContext(context)), - url_service_(TemplateURLServiceFactory::GetForProfile(profile_)), - extension_registry_observer_(this) { + url_service_(TemplateURLServiceFactory::GetForProfile(profile_)) { extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); if (url_service_) { template_url_sub_ = url_service_->RegisterOnLoadedCallback( diff --git a/chromium/chrome/browser/extensions/api/omnibox/omnibox_api.h b/chromium/chrome/browser/extensions/api/omnibox/omnibox_api.h index 435ea6456f9..9a648b7e6fb 100644 --- a/chromium/chrome/browser/extensions/api/omnibox/omnibox_api.h +++ b/chromium/chrome/browser/extensions/api/omnibox/omnibox_api.h @@ -18,6 +18,7 @@ #include "components/omnibox/browser/autocomplete_match.h" #include "components/search_engines/template_url_service.h" #include "extensions/browser/browser_context_keyed_api_factory.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry_observer.h" #include "ui/base/window_open_disposition.h" @@ -35,7 +36,6 @@ class Image; } namespace extensions { -class ExtensionRegistry; // Event router class for events related to the omnibox API. class ExtensionOmniboxEventRouter { @@ -134,7 +134,7 @@ class OmniboxAPI : public BrowserContextKeyedAPI, // Listen to extension load, unloaded notifications. ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - extension_registry_observer_; + extension_registry_observer_{this}; // Keeps track of favicon-sized omnibox icons for extensions. ExtensionIconManager omnibox_icon_manager_; diff --git a/chromium/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc b/chromium/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc index f07d7d273b8..7931d22b63e 100644 --- a/chromium/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc +++ b/chromium/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc @@ -265,6 +265,8 @@ void PasswordsPrivateDelegateImpl::SetPasswordList( IDS_PASSWORDS_VIA_FEDERATION, GetDisplayFederation(*form)))); } + entry.from_account_store = form->IsUsingAccountStore(); + current_entries_.push_back(std::move(entry)); } @@ -292,6 +294,8 @@ void PasswordsPrivateDelegateImpl::SetPasswordExceptionList( current_exception_entry.urls = CreateUrlCollectionFromForm(*form); current_exception_entry.id = exception_id_generator_.GenerateId( password_manager::CreateSortKey(*form)); + + current_exception_entry.from_account_store = form->IsUsingAccountStore(); current_exceptions_.push_back(std::move(current_exception_entry)); } diff --git a/chromium/chrome/browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc b/chromium/chrome/browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc index 2b6386c993b..2ae65f5c0f0 100644 --- a/chromium/chrome/browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc +++ b/chromium/chrome/browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc @@ -9,7 +9,6 @@ #include <utility> #include "base/bind.h" -#include "base/json/json_writer.h" #include "base/macros.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" @@ -28,8 +27,8 @@ #include "crypto/scoped_test_system_nss_key_slot.h" #include "net/cert/nss_cert_database.h" #include "net/cert/test_root_certs.h" +#include "net/cert/x509_certificate.h" #include "net/test/cert_test_util.h" -#include "net/test/test_data_directory.h" namespace { @@ -160,6 +159,10 @@ class PlatformKeysTest : public PlatformKeysTestBase { const extensions::Extension* extension_; private: + base::FilePath extension_path() const { + return test_data_dir_.AppendASCII("platform_keys"); + } + void SetPrivateSoftwareSlotOnIO(crypto::ScopedPK11Slot slot) { crypto::SetPrivateSoftwareSlotForChromeOSUserForTesting(std::move(slot)); } @@ -193,25 +196,23 @@ class PlatformKeysTest : public PlatformKeysTestBase { ? cert_db->GetPrivateSlot() : cert_db->GetPublicSlot(); client_cert1_ = net::ImportClientCertAndKeyFromFile( - net::GetTestCertsDirectory(), "client_1.pem", "client_1.pk8", - slot.get()); + extension_path(), "client_1.pem", "client_1.pk8", slot.get()); ASSERT_TRUE(client_cert1_.get()); // Import a second client cert signed by another CA than client_1 into the // system wide key slot. client_cert2_ = net::ImportClientCertAndKeyFromFile( - net::GetTestCertsDirectory(), "client_2.pem", "client_2.pk8", + extension_path(), "client_2.pem", "client_2.pk8", test_system_slot()->slot()); ASSERT_TRUE(client_cert2_.get()); } void SetupTestCACerts() { net::TestRootCerts* root_certs = net::TestRootCerts::GetInstance(); - // "root_ca_cert.pem" is the issuer of "ok_cert.pem" which is loaded on the - // JS side. Generated by create_test_certs.sh . - base::FilePath extension_path = test_data_dir_.AppendASCII("platform_keys"); - root_certs->AddFromFile( - test_data_dir_.AppendASCII("platform_keys").AppendASCII("root.pem")); + // "root.pem" is the issuer of the "l1_leaf.pem" and (transitively) + // "l1_leaf.pem" certs which are loaded on the JS side. Generated by + // create_test_certs.sh . + root_certs->AddFromFile(extension_path().AppendASCII("root.pem")); } const bool key_permission_policy_; diff --git a/chromium/chrome/browser/extensions/api/platform_keys/verify_trust_api.cc b/chromium/chrome/browser/extensions/api/platform_keys/verify_trust_api.cc index 7462a0021d7..3fa500422e4 100644 --- a/chromium/chrome/browser/extensions/api/platform_keys/verify_trust_api.cc +++ b/chromium/chrome/browser/extensions/api/platform_keys/verify_trust_api.cc @@ -91,7 +91,7 @@ void BrowserContextKeyedAPIFactory< } VerifyTrustAPI::VerifyTrustAPI(content::BrowserContext* context) - : io_part_(new IOPart), registry_observer_(this) { + : io_part_(new IOPart) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); registry_observer_.Add(ExtensionRegistry::Get(context)); } diff --git a/chromium/chrome/browser/extensions/api/platform_keys/verify_trust_api.h b/chromium/chrome/browser/extensions/api/platform_keys/verify_trust_api.h index 7c08e3d6a3e..f3b21ee674f 100644 --- a/chromium/chrome/browser/extensions/api/platform_keys/verify_trust_api.h +++ b/chromium/chrome/browser/extensions/api/platform_keys/verify_trust_api.h @@ -98,7 +98,7 @@ class VerifyTrustAPI : public BrowserContextKeyedAPI, std::unique_ptr<IOPart, content::BrowserThread::DeleteOnIOThread> io_part_; ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - registry_observer_; + registry_observer_{this}; base::WeakPtrFactory<VerifyTrustAPI> weak_factory_{this}; diff --git a/chromium/chrome/browser/extensions/api/preference/preference_api.cc b/chromium/chrome/browser/extensions/api/preference/preference_api.cc index d8d88361618..f961cdda093 100644 --- a/chromium/chrome/browser/extensions/api/preference/preference_api.cc +++ b/chromium/chrome/browser/extensions/api/preference/preference_api.cc @@ -17,14 +17,12 @@ #include "base/strings/stringprintf.h" #include "base/values.h" #include "build/build_config.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/api/content_settings/content_settings_service.h" #include "chrome/browser/extensions/api/preference/preference_api_constants.h" #include "chrome/browser/extensions/api/preference/preference_helpers.h" #include "chrome/browser/extensions/api/proxy/proxy_api.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/net/prediction_options.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" #include "components/autofill/core/common/autofill_prefs.h" #include "components/content_settings/core/common/pref_names.h" @@ -35,9 +33,6 @@ #include "components/safe_browsing/common/safe_browsing_prefs.h" #include "components/spellcheck/browser/pref_names.h" #include "components/translate/core/browser/translate_pref_names.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_source.h" #include "extensions/browser/extension_pref_value_map.h" #include "extensions/browser/extension_pref_value_map_factory.h" #include "extensions/browser/extension_prefs.h" @@ -364,14 +359,15 @@ PreferenceEventRouter::PreferenceEventRouter(Profile* profile) base::Bind(&PreferenceEventRouter::OnPrefChanged, base::Unretained(this), registrar_.prefs())); } - notification_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED, - content::NotificationService::AllSources()); - notification_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, - content::NotificationService::AllSources()); - OnIncognitoProfileCreated(profile->GetOffTheRecordPrefs()); + DCHECK(!profile_->IsOffTheRecord()); + observed_profiles_.Add(profile_); + if (profile->HasOffTheRecordProfile()) + OnOffTheRecordProfileCreated(profile->GetOffTheRecordProfile()); + else + ObserveOffTheRecordPrefs(profile->GetReadOnlyOffTheRecordPrefs()); } -PreferenceEventRouter::~PreferenceEventRouter() { } +PreferenceEventRouter::~PreferenceEventRouter() = default; void PreferenceEventRouter::OnPrefChanged(PrefService* pref_service, const std::string& browser_pref) { @@ -423,33 +419,22 @@ void PreferenceEventRouter::OnPrefChanged(PrefService* pref_service, browser_pref); } -void PreferenceEventRouter::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - switch (type) { - case chrome::NOTIFICATION_PROFILE_CREATED: { - Profile* profile = content::Source<Profile>(source).ptr(); - if (profile != profile_ && profile->GetOriginalProfile() == profile_) { - OnIncognitoProfileCreated(profile->GetPrefs()); - } - break; - } - case chrome::NOTIFICATION_PROFILE_DESTROYED: { - Profile* profile = content::Source<Profile>(source).ptr(); - if (profile != profile_ && profile->GetOriginalProfile() == profile_) { - // The real PrefService is about to be destroyed so we must make sure we - // get the "dummy" one. - OnIncognitoProfileCreated(profile_->GetReadOnlyOffTheRecordPrefs()); - } - break; - } - default: - NOTREACHED(); +void PreferenceEventRouter::OnOffTheRecordProfileCreated( + Profile* off_the_record) { + observed_profiles_.Add(off_the_record); + ObserveOffTheRecordPrefs(off_the_record->GetPrefs()); +} + +void PreferenceEventRouter::OnProfileWillBeDestroyed(Profile* profile) { + observed_profiles_.Remove(profile); + if (profile->IsOffTheRecord()) { + // The real PrefService is about to be destroyed so we must make sure we + // get the "dummy" one. + ObserveOffTheRecordPrefs(profile_->GetReadOnlyOffTheRecordPrefs()); } } -void PreferenceEventRouter::OnIncognitoProfileCreated(PrefService* prefs) { +void PreferenceEventRouter::ObserveOffTheRecordPrefs(PrefService* prefs) { incognito_registrar_ = std::make_unique<PrefChangeRegistrar>(); incognito_registrar_->Init(prefs); for (const auto& pref : kPrefMapping) { diff --git a/chromium/chrome/browser/extensions/api/preference/preference_api.h b/chromium/chrome/browser/extensions/api/preference/preference_api.h index 086434a7653..fbb632013c7 100644 --- a/chromium/chrome/browser/extensions/api/preference/preference_api.h +++ b/chromium/chrome/browser/extensions/api/preference/preference_api.h @@ -10,11 +10,12 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/scoped_observer.h" #include "chrome/browser/extensions/api/content_settings/content_settings_store.h" #include "chrome/browser/extensions/chrome_extension_function.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_observer.h" #include "components/prefs/pref_change_registrar.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" #include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_prefs_scope.h" @@ -29,7 +30,7 @@ class Value; namespace extensions { class ExtensionPrefs; -class PreferenceEventRouter : public content::NotificationObserver { +class PreferenceEventRouter : public ProfileObserver { public: explicit PreferenceEventRouter(Profile* profile); ~PreferenceEventRouter() override; @@ -38,20 +39,20 @@ class PreferenceEventRouter : public content::NotificationObserver { void OnPrefChanged(PrefService* pref_service, const std::string& pref_key); - // content::NotificationObserver: - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; + // ProfileObserver: + void OnOffTheRecordProfileCreated(Profile* off_the_record) override; + void OnProfileWillBeDestroyed(Profile* profile) override; - void OnIncognitoProfileCreated(PrefService* prefs); + void ObserveOffTheRecordPrefs(PrefService* prefs); - content::NotificationRegistrar notification_registrar_; PrefChangeRegistrar registrar_; std::unique_ptr<PrefChangeRegistrar> incognito_registrar_; // Weak, owns us (transitively via ExtensionService). Profile* profile_; + ScopedObserver<Profile, ProfileObserver> observed_profiles_{this}; + DISALLOW_COPY_AND_ASSIGN(PreferenceEventRouter); }; diff --git a/chromium/chrome/browser/extensions/api/preference/preference_apitest.cc b/chromium/chrome/browser/extensions/api/preference/preference_apitest.cc index 10321960008..a347e5d47b0 100644 --- a/chromium/chrome/browser/extensions/api/preference/preference_apitest.cc +++ b/chromium/chrome/browser/extensions/api/preference/preference_apitest.cc @@ -29,12 +29,12 @@ #include "components/safe_browsing/common/safe_browsing_prefs.h" #include "components/translate/core/browser/translate_pref_names.h" #include "content/public/browser/notification_service.h" -#include "content/public/common/webrtc_ip_handling_policy.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/test_extension_registry_observer.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" #include "media/media_buildflags.h" +#include "third_party/blink/public/common/peerconnection/webrtc_ip_handling_policy.h" class ExtensionPreferenceApiTest : public extensions::ExtensionApiTest { protected: @@ -139,7 +139,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionPreferenceApiTest, MAYBE_Standard) { prefs->SetBoolean(prefs::kWebRTCMultipleRoutesEnabled, false); prefs->SetBoolean(prefs::kWebRTCNonProxiedUdpEnabled, false); prefs->SetString(prefs::kWebRTCIPHandlingPolicy, - content::kWebRTCIPHandlingDefaultPublicInterfaceOnly); + blink::kWebRTCIPHandlingDefaultPublicInterfaceOnly); const char kExtensionPath[] = "preference/standard"; diff --git a/chromium/chrome/browser/extensions/api/processes/processes_api.cc b/chromium/chrome/browser/extensions/api/processes/processes_api.cc index 093fa4fd495..30d45fe2144 100644 --- a/chromium/chrome/browser/extensions/api/processes/processes_api.cc +++ b/chromium/chrome/browser/extensions/api/processes/processes_api.cc @@ -33,7 +33,6 @@ #include "content/public/common/child_process_host.h" #include "content/public/common/result_codes.h" #include "extensions/common/error_utils.h" -#include "third_party/blink/public/platform/web_cache.h" namespace extensions { @@ -65,7 +64,7 @@ int64_t GetRefreshTypesForProcessOptionalData() { } std::unique_ptr<api::processes::Cache> CreateCacheData( - const blink::WebCache::ResourceTypeStat& stat) { + const blink::WebCacheResourceTypeStat& stat) { std::unique_ptr<api::processes::Cache> cache(new api::processes::Cache()); cache->size = static_cast<double>(stat.size); cache->live_size = static_cast<double>(stat.size); @@ -168,7 +167,7 @@ void FillProcessData( sqlite_bytes))); } - blink::WebCache::ResourceTypeStats cache_stats; + blink::WebCacheResourceTypeStats cache_stats; if (task_manager->GetWebCacheStats(id, &cache_stats)) { out_process->image_cache = CreateCacheData(cache_stats.images); out_process->script_cache = CreateCacheData(cache_stats.scripts); diff --git a/chromium/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc b/chromium/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc index 06c58128a08..35898e2e8f3 100644 --- a/chromium/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc +++ b/chromium/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc @@ -28,7 +28,6 @@ #include "chrome/browser/ui/browser_window.h" #include "components/update_client/update_query_params.h" #include "content/public/browser/notification_service.h" -#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/notification_types.h" #include "extensions/browser/warning_service.h" @@ -145,9 +144,7 @@ struct ChromeRuntimeAPIDelegate::UpdateCheckInfo { ChromeRuntimeAPIDelegate::ChromeRuntimeAPIDelegate( content::BrowserContext* context) - : browser_context_(context), - registered_for_updates_(false), - extension_registry_observer_(this) { + : browser_context_(context), registered_for_updates_(false) { registrar_.Add(this, extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND, content::NotificationService::AllSources()); @@ -267,9 +264,12 @@ bool ChromeRuntimeAPIDelegate::CheckForUpdates( true, kUpdateThrottled, ""))); } else { info.callbacks.push_back(callback); - updater->CheckExtensionSoon( - extension_id, base::Bind(&ChromeRuntimeAPIDelegate::UpdateCheckComplete, - base::Unretained(this), extension_id)); + + extensions::ExtensionUpdater::CheckParams params; + params.ids = {extension_id}; + params.callback = base::Bind(&ChromeRuntimeAPIDelegate::UpdateCheckComplete, + base::Unretained(this), extension_id); + updater->CheckNow(std::move(params)); } return true; } diff --git a/chromium/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.h b/chromium/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.h index 3b1951383f0..7abc7209460 100644 --- a/chromium/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.h +++ b/chromium/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.h @@ -15,6 +15,7 @@ #include "content/public/browser/notification_registrar.h" #include "extensions/browser/api/runtime/runtime_api.h" #include "extensions/browser/api/runtime/runtime_api_delegate.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry_observer.h" namespace base { @@ -29,7 +30,6 @@ class NotificationSource; } namespace extensions { -class ExtensionRegistry; class RuntimeAPI; class UpdateObserver; } @@ -92,7 +92,7 @@ class ChromeRuntimeAPIDelegate : public extensions::RuntimeAPIDelegate, ScopedObserver<extensions::ExtensionRegistry, extensions::ExtensionRegistryObserver> - extension_registry_observer_; + extension_registry_observer_{this}; DISALLOW_COPY_AND_ASSIGN(ChromeRuntimeAPIDelegate); }; diff --git a/chromium/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate_unittest.cc b/chromium/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate_unittest.cc index af092f1be71..c227368864d 100644 --- a/chromium/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate_unittest.cc +++ b/chromium/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate_unittest.cc @@ -334,7 +334,7 @@ TEST_F(ChromeRuntimeAPIDelegateTest, RequestUpdateCheck) { class ExtensionLoadWaiter : public ExtensionRegistryObserver { public: explicit ExtensionLoadWaiter(content::BrowserContext* context) - : context_(context), extension_registry_observer_(this) { + : context_(context) { extension_registry_observer_.Add(ExtensionRegistry::Get(context_)); } @@ -366,7 +366,7 @@ class ExtensionLoadWaiter : public ExtensionRegistryObserver { base::RunLoop run_loop_; content::BrowserContext* context_; ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - extension_registry_observer_; + extension_registry_observer_{this}; DISALLOW_COPY_AND_ASSIGN(ExtensionLoadWaiter); }; diff --git a/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api_unittest.cc b/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api_unittest.cc index bafb52e22ec..fdbd0c31876 100644 --- a/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api_unittest.cc +++ b/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api_unittest.cc @@ -101,7 +101,7 @@ void SafeBrowsingPrivateApiUnitTest::SetUp() { TestingBrowserProcess::GetGlobal()->SetSafeBrowsingService( safe_browsing_service); g_browser_process->safe_browsing_service()->Initialize(); - safe_browsing_service->AddPrefService(profile()->GetPrefs()); + safe_browsing_service->OnProfileAdded(profile()); } void SafeBrowsingPrivateApiUnitTest::TearDown() { diff --git a/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc b/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc index 7b0692cb8de..31c8db61f5f 100644 --- a/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc +++ b/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc @@ -16,6 +16,7 @@ #include "chrome/browser/profiles/profile_attributes_entry.h" #include "chrome/browser/profiles/profile_attributes_storage.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/profiles/reporting_util.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/common/extensions/api/safe_browsing_private.h" #include "components/policy/core/common/cloud/cloud_policy_client.h" @@ -33,7 +34,7 @@ namespace extensions { const base::Feature SafeBrowsingPrivateEventRouter::kRealtimeReportingFeature{ - "SafeBrowsingRealtimeReporting", base::FEATURE_ENABLED_BY_DEFAULT}; + "SafeBrowsingRealtimeReporting", base::FEATURE_DISABLED_BY_DEFAULT}; // Key names used with when building the dictionary to pass to the real-time // reporting API. @@ -53,6 +54,9 @@ const char SafeBrowsingPrivateEventRouter::kKeyClickedThrough[] = const char SafeBrowsingPrivateEventRouter::kKeyTriggeredRules[] = "triggeredRules"; const char SafeBrowsingPrivateEventRouter::kKeyThreatType[] = "threatType"; +const char SafeBrowsingPrivateEventRouter::kKeyContentType[] = "contentType"; +const char SafeBrowsingPrivateEventRouter::kKeyContentSize[] = "contentSize"; +const char SafeBrowsingPrivateEventRouter::kKeyTrigger[] = "trigger"; const char SafeBrowsingPrivateEventRouter::kKeyPasswordReuseEvent[] = "passwordReuseEvent"; @@ -67,6 +71,12 @@ const char SafeBrowsingPrivateEventRouter::kKeySensitiveDataEvent[] = const char SafeBrowsingPrivateEventRouter::kKeyLargeUnscannedFileEvent[] = "largeUnscannedFileEvent"; +const char SafeBrowsingPrivateEventRouter::kTriggerFileDownload[] = + "FILE_DOWNLOAD"; +const char SafeBrowsingPrivateEventRouter::kTriggerFileUpload[] = "FILE_UPLOAD"; +const char SafeBrowsingPrivateEventRouter::kTriggerWebContentUpload[] = + "WEB_CONTENT_UPLOAD"; + SafeBrowsingPrivateEventRouter::SafeBrowsingPrivateEventRouter( content::BrowserContext* context) : context_(context) { @@ -85,30 +95,6 @@ SafeBrowsingPrivateEventRouter::SafeBrowsingPrivateEventRouter( } } -// TODO(rogerta): once new event types are implemented, will likely want to -// move this to a more common place. -base::Value BuildRealtimeReport(Profile* profile, base::Value event) { - base::Value context(base::Value::Type::DICTIONARY); - - ProfileAttributesStorage& storage = - g_browser_process->profile_manager()->GetProfileAttributesStorage(); - ProfileAttributesEntry* entry = nullptr; - if (storage.GetProfileAttributesWithPath(profile->GetPath(), &entry)) { - context.SetStringPath("profile.profileName", entry->GetName()); - context.SetStringPath("profile.gaiaEmail", entry->GetUserName()); - } - - context.SetStringPath("profile.profilePath", profile->GetPath().value()); - context.SetStringPath("browser.userAgent", GetUserAgent()); - - base::Value report(base::Value::Type::DICTIONARY); - report.SetKey(policy::RealtimeReportingJobConfiguration::kContextKey, - std::move(context)); - report.SetKey(policy::RealtimeReportingJobConfiguration::kEventKey, - std::move(event)); - return report; -} - SafeBrowsingPrivateEventRouter::~SafeBrowsingPrivateEventRouter() {} void SafeBrowsingPrivateEventRouter::OnPolicySpecifiedPasswordReuseDetected( @@ -171,7 +157,9 @@ void SafeBrowsingPrivateEventRouter::OnPolicySpecifiedPasswordChanged( void SafeBrowsingPrivateEventRouter::OnDangerousDownloadOpened( const GURL& url, const std::string& file_name, - const std::string& download_digest_sha256) { + const std::string& download_digest_sha256, + const std::string& mime_type, + const int64_t content_size) { api::safe_browsing_private::DangerousDownloadInfo params; params.url = url.spec(); params.file_name = file_name; @@ -197,6 +185,12 @@ void SafeBrowsingPrivateEventRouter::OnDangerousDownloadOpened( event.SetStringKey(kKeyFileName, params.file_name); event.SetStringKey(kKeyDownloadDigestSha256, params.download_digest_sha256); event.SetStringKey(kKeyProfileUserName, params.user_name); + event.SetStringKey(kKeyContentType, mime_type); + // |content_size| can be set to -1 to indicate an unknown size, in which + // case the field is not set. + if (content_size >= 0) + event.SetIntKey(kKeyContentSize, content_size); + event.SetStringKey(kKeyTrigger, kTriggerFileDownload); ReportRealtimeEvent(kKeyDangerousDownloadEvent, std::move(event)); } } @@ -279,7 +273,10 @@ void SafeBrowsingPrivateEventRouter::OnDangerousDeepScanningResult( const GURL& url, const std::string& file_name, const std::string& download_digest_sha256, - const std::string& threat_type) { + const std::string& threat_type, + const std::string& mime_type, + const std::string& trigger, + const int64_t content_size) { if (IsRealtimeReportingEnabled()) { // Create a real-time event dictionary from the arguments and report it. base::Value event(base::Value::Type::DICTIONARY); @@ -288,6 +285,12 @@ void SafeBrowsingPrivateEventRouter::OnDangerousDeepScanningResult( event.SetStringKey(kKeyDownloadDigestSha256, download_digest_sha256); event.SetStringKey(kKeyProfileUserName, GetProfileUserName()); event.SetStringKey(kKeyThreatType, threat_type); + event.SetStringKey(kKeyContentType, mime_type); + // |content_size| can be set to -1 to indicate an unknown size, in which + // case the field is not set. + if (content_size >= 0) + event.SetIntKey(kKeyContentSize, content_size); + event.SetStringKey(kKeyTrigger, trigger); ReportRealtimeEvent(kKeyDangerousDownloadEvent, std::move(event)); } } @@ -296,7 +299,10 @@ void SafeBrowsingPrivateEventRouter::OnSensitiveDataEvent( const safe_browsing::DlpDeepScanningVerdict& verdict, const GURL& url, const std::string& file_name, - const std::string& download_digest_sha256) { + const std::string& download_digest_sha256, + const std::string& mime_type, + const std::string& trigger, + const int64_t content_size) { if (IsRealtimeReportingEnabled()) { // Create a real-time event dictionary from the arguments and report it. base::Value event(base::Value::Type::DICTIONARY); @@ -304,6 +310,12 @@ void SafeBrowsingPrivateEventRouter::OnSensitiveDataEvent( event.SetStringKey(kKeyFileName, file_name); event.SetStringKey(kKeyDownloadDigestSha256, download_digest_sha256); event.SetStringKey(kKeyProfileUserName, GetProfileUserName()); + event.SetStringKey(kKeyContentType, mime_type); + // |content_size| can be set to -1 to indicate an unknown size, in which + // case the field is not set. + if (content_size >= 0) + event.SetIntKey(kKeyContentSize, content_size); + event.SetStringKey(kKeyTrigger, trigger); base::ListValue triggered_rules; for (auto rule : verdict.triggered_rules()) { @@ -317,7 +329,10 @@ void SafeBrowsingPrivateEventRouter::OnSensitiveDataEvent( void SafeBrowsingPrivateEventRouter::OnLargeUnscannedFileEvent( const GURL& url, const std::string& file_name, - const std::string& download_digest_sha256) { + const std::string& download_digest_sha256, + const std::string& mime_type, + const std::string& trigger, + const int64_t content_size) { if (IsRealtimeReportingEnabled()) { // Create a real-time event dictionary from the arguments and report it. base::Value event(base::Value::Type::DICTIONARY); @@ -325,10 +340,70 @@ void SafeBrowsingPrivateEventRouter::OnLargeUnscannedFileEvent( event.SetStringKey(kKeyFileName, file_name); event.SetStringKey(kKeyDownloadDigestSha256, download_digest_sha256); event.SetStringKey(kKeyProfileUserName, GetProfileUserName()); + event.SetStringKey(kKeyContentType, mime_type); + // |content_size| can be set to -1 to indicate an unknown size, in which + // case the field is not set. + if (content_size >= 0) + event.SetIntKey(kKeyContentSize, content_size); + event.SetStringKey(kKeyTrigger, trigger); ReportRealtimeEvent(kKeyLargeUnscannedFileEvent, std::move(event)); } } +void SafeBrowsingPrivateEventRouter::OnDangerousDownloadWarning( + const GURL& url, + const std::string& file_name, + const std::string& download_digest_sha256, + const std::string& threat_type, + const std::string& mime_type, + const int64_t content_size) { + if (!IsRealtimeReportingEnabled()) + return; + + // Create a real-time event dictionary and report it. + base::Value event(base::Value::Type::DICTIONARY); + event.SetStringKey(kKeyUrl, url.spec()); + event.SetStringKey(kKeyFileName, file_name); + event.SetStringKey(kKeyDownloadDigestSha256, download_digest_sha256); + event.SetStringKey(kKeyProfileUserName, GetProfileUserName()); + event.SetStringKey(kKeyThreatType, threat_type); + event.SetBoolKey(kKeyClickedThrough, false); + event.SetStringKey(kKeyContentType, mime_type); + // |content_size| can be set to -1 to indicate an unknown size, in which case + // the field is not set. + if (content_size >= 0) + event.SetIntKey(kKeyContentSize, content_size); + event.SetStringKey(kKeyTrigger, kTriggerFileDownload); + ReportRealtimeEvent(kKeyDangerousDownloadEvent, std::move(event)); +} + +void SafeBrowsingPrivateEventRouter::OnDangerousDownloadWarningBypassed( + const GURL& url, + const std::string& file_name, + const std::string& download_digest_sha256, + const std::string& threat_type, + const std::string& mime_type, + const int64_t content_size) { + if (!IsRealtimeReportingEnabled()) + return; + + // Create a real-time event dictionary and report it. + base::Value event(base::Value::Type::DICTIONARY); + event.SetStringKey(kKeyUrl, url.spec()); + event.SetStringKey(kKeyFileName, file_name); + event.SetStringKey(kKeyDownloadDigestSha256, download_digest_sha256); + event.SetStringKey(kKeyProfileUserName, GetProfileUserName()); + event.SetStringKey(kKeyThreatType, threat_type); + event.SetBoolKey(kKeyClickedThrough, true); + event.SetStringKey(kKeyContentType, mime_type); + // |content_size| can be set to -1 to indicate an unknown size, in which case + // the field is not set. + if (content_size >= 0) + event.SetIntKey(kKeyContentSize, content_size); + event.SetStringKey(kKeyTrigger, kTriggerFileDownload); + ReportRealtimeEvent(kKeyDangerousDownloadEvent, std::move(event)); +} + void SafeBrowsingPrivateEventRouter::SetCloudPolicyClientForTesting( std::unique_ptr<policy::CloudPolicyClient> client) { DCHECK_EQ(nullptr, client_.get()); @@ -337,14 +412,15 @@ void SafeBrowsingPrivateEventRouter::SetCloudPolicyClientForTesting( void SafeBrowsingPrivateEventRouter::InitRealtimeReportingClient() { #if !defined(OS_CHROMEOS) - // This method is not compiled on chromeos because - // MachineLevelUserCloudPolicyController does not exist. Also, - // policy::BrowserDMTokenStorage::Get()->RetrieveDMToken() does return a - // valid token either. Once these are fixed the #if !define can be removed. // If already initialized, do nothing. if (client_) return; + // This method is not compiled on Chrome OS because + // MachineLevelUserCloudPolicyController does not exist. Also, + // policy::BrowserDMTokenStorage::Get()->RetrieveDMToken() doesn't return a + // valid token either. Once these are fixed the #if !defined can be removed. + if (!policy::MachineLevelUserCloudPolicyController:: IsMachineLevelUserCloudPolicyEnabled()) { return; @@ -435,9 +511,13 @@ void SafeBrowsingPrivateEventRouter::ReportRealtimeEvent(const char* name, wrapper.SetStringKey("time", now_str); wrapper.SetKey(name, std::move(event)); + base::Value event_list(base::Value::Type::LIST); + event_list.Append(std::move(wrapper)); + client_->UploadRealtimeReport( - BuildRealtimeReport(Profile::FromBrowserContext(context_), - std::move(wrapper)), + policy::RealtimeReportingJobConfiguration::BuildReport( + std::move(event_list), + reporting::GetContext(Profile::FromBrowserContext(context_))), base::DoNothing()); } diff --git a/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h b/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h index 9a3441613dc..754a73b3f64 100644 --- a/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h +++ b/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h @@ -59,6 +59,9 @@ class SafeBrowsingPrivateEventRouter : public KeyedService { static const char kKeyClickedThrough[]; static const char kKeyTriggeredRules[]; static const char kKeyThreatType[]; + static const char kKeyContentType[]; + static const char kKeyContentSize[]; + static const char kKeyTrigger[]; static const char kKeyPasswordReuseEvent[]; static const char kKeyPasswordChangedEvent[]; @@ -67,6 +70,11 @@ class SafeBrowsingPrivateEventRouter : public KeyedService { static const char kKeySensitiveDataEvent[]; static const char kKeyLargeUnscannedFileEvent[]; + // String constants for the "trigger" event field. + static const char kTriggerFileDownload[]; + static const char kTriggerFileUpload[]; + static const char kTriggerWebContentUpload[]; + explicit SafeBrowsingPrivateEventRouter(content::BrowserContext* context); ~SafeBrowsingPrivateEventRouter() override; @@ -83,7 +91,9 @@ class SafeBrowsingPrivateEventRouter : public KeyedService { // Notifies listeners that the user just opened a dangerous download. void OnDangerousDownloadOpened(const GURL& url, const std::string& file_name, - const std::string& download_digest_sha256); + const std::string& download_digest_sha256, + const std::string& mime_type, + const int64_t content_size); // Notifies listeners that the user saw a security interstitial. void OnSecurityInterstitialShown(const GURL& url, @@ -99,19 +109,53 @@ class SafeBrowsingPrivateEventRouter : public KeyedService { void OnDangerousDeepScanningResult(const GURL& url, const std::string& file_name, const std::string& download_digest_sha256, - const std::string& threat_type); + const std::string& threat_type, + const std::string& mime_type, + const std::string& trigger, + const int64_t content_size); // Notifies listeners that scanning for sensitive data detected a violation. void OnSensitiveDataEvent( const safe_browsing::DlpDeepScanningVerdict& verdict, const GURL& url, const std::string& file_name, - const std::string& download_digest_sha256); + const std::string& download_digest_sha256, + const std::string& mime_type, + const std::string& trigger, + const int64_t content_size); // Notifies listeners that deep scanning failed, since the file was too large. void OnLargeUnscannedFileEvent(const GURL& url, const std::string& file_name, - const std::string& download_digest_sha256); + const std::string& download_digest_sha256, + const std::string& mime_type, + const std::string& trigger, + const int64_t content_size); + + // Notifies listeners that the user saw a download warning. + // - |url| is the download URL + // - |file_name| is the path on disk + // - |download_digest_sha256| is the hex-encoded SHA256 + // - |threat_type| is the danger type of the download. + void OnDangerousDownloadWarning(const GURL& url, + const std::string& file_name, + const std::string& download_digest_sha256, + const std::string& threat_type, + const std::string& mime_type, + const int64_t content_size); + + // Notifies listeners that the user bypassed a download warning. + // - |url| is the download URL + // - |file_name| is the path on disk + // - |download_digest_sha256| is the hex-encoded SHA256 + // - |threat_type| is the danger type of the download. + void OnDangerousDownloadWarningBypassed( + const GURL& url, + const std::string& file_name, + const std::string& download_digest_sha256, + const std::string& threat_type, + const std::string& mime_type, + const int64_t content_size); void SetCloudPolicyClientForTesting( std::unique_ptr<policy::CloudPolicyClient> client); diff --git a/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_unittest.cc b/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_unittest.cc index 26c8393207c..b0085a1e5d2 100644 --- a/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_unittest.cc +++ b/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_unittest.cc @@ -4,6 +4,7 @@ #include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h" #include "base/bind.h" +#include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "base/test/mock_callback.h" #include "base/values.h" @@ -94,7 +95,7 @@ class SafeBrowsingPrivateEventRouterTest : public testing::Test { SafeBrowsingPrivateEventRouterFactory::GetForProfile(profile_) ->OnDangerousDownloadOpened(GURL("https://evil.com/malware.exe"), "/path/to/malware.exe", - "sha256_or_malware_exe"); + "sha256_of_malware_exe", "exe", 1234); } void TriggerOnSecurityInterstitialShownEvent() { @@ -109,6 +110,20 @@ class SafeBrowsingPrivateEventRouterTest : public testing::Test { "PHISHING", -201); } + void TriggerOnDangerousDownloadWarningEvent() { + SafeBrowsingPrivateEventRouterFactory::GetForProfile(profile_) + ->OnDangerousDownloadWarning( + GURL("https://maybevil.com/warning.exe"), "/path/to/warning.exe", + "sha256_of_warning_exe", "POTENTIALLY_UNWANTED", "exe", 567); + } + + void TriggerOnDangerousDownloadWarningEventBypass() { + SafeBrowsingPrivateEventRouterFactory::GetForProfile(profile_) + ->OnDangerousDownloadWarning( + GURL("https://bypassevil.com/bypass.exe"), "/path/to/bypass.exe", + "sha256_of_bypass_exe", "BYPASSED_WARNING", "exe", 890); + } + void SetReportingPolicy(bool enabled) { TestingBrowserProcess::GetGlobal()->local_state()->SetBoolean( prefs::kUnsafeEventsReportingEnabled, enabled); @@ -166,12 +181,16 @@ TEST_F(SafeBrowsingPrivateEventRouterTest, TestOnReuseDetected) { Mock::VerifyAndClearExpectations(client_); EXPECT_EQ(base::Value::Type::DICTIONARY, report.type()); - base::Value* wrapper = - report.FindKey(policy::RealtimeReportingJobConfiguration::kEventKey); - ASSERT_NE(nullptr, wrapper); - EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper->type()); + base::Value* event_list = + report.FindKey(policy::RealtimeReportingJobConfiguration::kEventListKey); + ASSERT_NE(nullptr, event_list); + EXPECT_EQ(base::Value::Type::LIST, event_list->type()); + base::Value::ListStorage& mutable_list = event_list->GetList(); + ASSERT_EQ(1, (int)mutable_list.size()); + base::Value wrapper = std::move(mutable_list[0]); + EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper.type()); base::Value* event = - wrapper->FindKey(SafeBrowsingPrivateEventRouter::kKeyPasswordReuseEvent); + wrapper.FindKey(SafeBrowsingPrivateEventRouter::kKeyPasswordReuseEvent); EXPECT_NE(nullptr, event); EXPECT_EQ("https://phishing.com/", *event->FindStringKey(SafeBrowsingPrivateEventRouter::kKeyUrl)); @@ -197,12 +216,16 @@ TEST_F(SafeBrowsingPrivateEventRouterTest, TestOnPasswordChanged) { Mock::VerifyAndClearExpectations(client_); EXPECT_EQ(base::Value::Type::DICTIONARY, report.type()); - base::Value* wrapper = - report.FindKey(policy::RealtimeReportingJobConfiguration::kEventKey); - ASSERT_NE(nullptr, wrapper); - EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper->type()); - base::Value* event = wrapper->FindKey( - SafeBrowsingPrivateEventRouter::kKeyPasswordChangedEvent); + base::Value* event_list = + report.FindKey(policy::RealtimeReportingJobConfiguration::kEventListKey); + ASSERT_NE(nullptr, event_list); + EXPECT_EQ(base::Value::Type::LIST, event_list->type()); + base::Value::ListStorage& mutable_list = event_list->GetList(); + ASSERT_EQ(1, (int)mutable_list.size()); + base::Value wrapper = std::move(mutable_list[0]); + EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper.type()); + base::Value* event = + wrapper.FindKey(SafeBrowsingPrivateEventRouter::kKeyPasswordChangedEvent); EXPECT_NE(nullptr, event); EXPECT_EQ("user_name_2", *event->FindStringKey( SafeBrowsingPrivateEventRouter::kKeyUserName)); @@ -227,21 +250,31 @@ TEST_F(SafeBrowsingPrivateEventRouterTest, TestOnDangerousDownloadOpened) { EXPECT_EQ("/path/to/malware.exe", captured_args.FindKey("fileName")->GetString()); EXPECT_EQ("", captured_args.FindKey("userName")->GetString()); - EXPECT_EQ("sha256_or_malware_exe", + EXPECT_EQ("sha256_of_malware_exe", captured_args.FindKey("downloadDigestSha256")->GetString()); Mock::VerifyAndClearExpectations(client_); EXPECT_EQ(base::Value::Type::DICTIONARY, report.type()); - base::Value* wrapper = - report.FindKey(policy::RealtimeReportingJobConfiguration::kEventKey); - ASSERT_NE(nullptr, wrapper); - EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper->type()); - base::Value* event = wrapper->FindKey( + base::Value* event_list = + report.FindKey(policy::RealtimeReportingJobConfiguration::kEventListKey); + ASSERT_NE(nullptr, event_list); + EXPECT_EQ(base::Value::Type::LIST, event_list->type()); + base::Value::ListStorage& mutable_list = event_list->GetList(); + ASSERT_EQ(1, (int)mutable_list.size()); + base::Value wrapper = std::move(mutable_list[0]); + EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper.type()); + base::Value* event = wrapper.FindKey( SafeBrowsingPrivateEventRouter::kKeyDangerousDownloadEvent); EXPECT_NE(nullptr, event); EXPECT_EQ( "/path/to/malware.exe", *event->FindStringKey(SafeBrowsingPrivateEventRouter::kKeyFileName)); + EXPECT_EQ("exe", *event->FindStringKey( + SafeBrowsingPrivateEventRouter::kKeyContentType)); + EXPECT_EQ(1234, *event->FindIntKey( + SafeBrowsingPrivateEventRouter::kKeyContentSize)); + EXPECT_EQ(SafeBrowsingPrivateEventRouter::kTriggerFileDownload, + *event->FindStringKey(SafeBrowsingPrivateEventRouter::kKeyTrigger)); } TEST_F(SafeBrowsingPrivateEventRouterTest, @@ -266,12 +299,16 @@ TEST_F(SafeBrowsingPrivateEventRouterTest, Mock::VerifyAndClearExpectations(client_); EXPECT_EQ(base::Value::Type::DICTIONARY, report.type()); - base::Value* wrapper = - report.FindKey(policy::RealtimeReportingJobConfiguration::kEventKey); - ASSERT_NE(nullptr, wrapper); - EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper->type()); + base::Value* event_list = + report.FindKey(policy::RealtimeReportingJobConfiguration::kEventListKey); + ASSERT_NE(nullptr, event_list); + EXPECT_EQ(base::Value::Type::LIST, event_list->type()); + base::Value::ListStorage& mutable_list = event_list->GetList(); + ASSERT_EQ(1, (int)mutable_list.size()); + base::Value wrapper = std::move(mutable_list[0]); + EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper.type()); base::Value* event = - wrapper->FindKey(SafeBrowsingPrivateEventRouter::kKeyInterstitialEvent); + wrapper.FindKey(SafeBrowsingPrivateEventRouter::kKeyInterstitialEvent); EXPECT_NE(nullptr, event); EXPECT_EQ("PHISHING", *event->FindStringKey(SafeBrowsingPrivateEventRouter::kKeyReason)); @@ -302,12 +339,16 @@ TEST_F(SafeBrowsingPrivateEventRouterTest, TestOnSecurityInterstitialShown) { Mock::VerifyAndClearExpectations(client_); EXPECT_EQ(base::Value::Type::DICTIONARY, report.type()); - base::Value* wrapper = - report.FindKey(policy::RealtimeReportingJobConfiguration::kEventKey); - ASSERT_NE(nullptr, wrapper); - EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper->type()); + base::Value* event_list = + report.FindKey(policy::RealtimeReportingJobConfiguration::kEventListKey); + ASSERT_NE(nullptr, event_list); + EXPECT_EQ(base::Value::Type::LIST, event_list->type()); + base::Value::ListStorage& mutable_list = event_list->GetList(); + ASSERT_EQ(1, (int)mutable_list.size()); + base::Value wrapper = std::move(mutable_list[0]); + EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper.type()); base::Value* event = - wrapper->FindKey(SafeBrowsingPrivateEventRouter::kKeyInterstitialEvent); + wrapper.FindKey(SafeBrowsingPrivateEventRouter::kKeyInterstitialEvent); EXPECT_NE(nullptr, event); EXPECT_EQ("PHISHING", *event->FindStringKey(SafeBrowsingPrivateEventRouter::kKeyReason)); @@ -317,6 +358,83 @@ TEST_F(SafeBrowsingPrivateEventRouterTest, TestOnSecurityInterstitialShown) { *event->FindBoolKey(SafeBrowsingPrivateEventRouter::kKeyClickedThrough)); } +TEST_F(SafeBrowsingPrivateEventRouterTest, TestOnDangerousDownloadWarning) { + SetUpRouters(); + SafeBrowsingEventObserver event_observer( + api::safe_browsing_private::OnDangerousDownloadOpened::kEventName); + event_router_->AddEventObserver(&event_observer); + + base::Value report; + EXPECT_CALL(*client_, UploadRealtimeReport(_, _)) + .WillOnce(CaptureArg(&report)); + + TriggerOnDangerousDownloadWarningEvent(); + base::RunLoop().RunUntilIdle(); + + Mock::VerifyAndClearExpectations(client_); + EXPECT_EQ(base::Value::Type::DICTIONARY, report.type()); + base::Value* event_list = + report.FindKey(policy::RealtimeReportingJobConfiguration::kEventListKey); + ASSERT_NE(nullptr, event_list); + EXPECT_EQ(base::Value::Type::LIST, event_list->type()); + base::Value::ListStorage& mutable_list = event_list->GetList(); + ASSERT_EQ(1, (int)mutable_list.size()); + base::Value wrapper = std::move(mutable_list[0]); + EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper.type()); + base::Value* event = wrapper.FindKey( + SafeBrowsingPrivateEventRouter::kKeyDangerousDownloadEvent); + EXPECT_NE(nullptr, event); + EXPECT_EQ( + "/path/to/warning.exe", + *event->FindStringKey(SafeBrowsingPrivateEventRouter::kKeyFileName)); + EXPECT_EQ("exe", *event->FindStringKey( + SafeBrowsingPrivateEventRouter::kKeyContentType)); + EXPECT_EQ( + 567, *event->FindIntKey(SafeBrowsingPrivateEventRouter::kKeyContentSize)); + EXPECT_EQ( + "POTENTIALLY_UNWANTED", + *event->FindStringKey(SafeBrowsingPrivateEventRouter::kKeyThreatType)); +} + +TEST_F(SafeBrowsingPrivateEventRouterTest, + TestOnDangerousDownloadWarningBypass) { + SetUpRouters(); + SafeBrowsingEventObserver event_observer( + api::safe_browsing_private::OnDangerousDownloadOpened::kEventName); + event_router_->AddEventObserver(&event_observer); + + base::Value report; + EXPECT_CALL(*client_, UploadRealtimeReport(_, _)) + .WillOnce(CaptureArg(&report)); + + TriggerOnDangerousDownloadWarningEventBypass(); + base::RunLoop().RunUntilIdle(); + + Mock::VerifyAndClearExpectations(client_); + EXPECT_EQ(base::Value::Type::DICTIONARY, report.type()); + base::Value* event_list = + report.FindKey(policy::RealtimeReportingJobConfiguration::kEventListKey); + ASSERT_NE(nullptr, event_list); + EXPECT_EQ(base::Value::Type::LIST, event_list->type()); + base::Value::ListStorage& mutable_list = event_list->GetList(); + ASSERT_EQ(1, (int)mutable_list.size()); + base::Value wrapper = std::move(mutable_list[0]); + EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper.type()); + base::Value* event = wrapper.FindKey( + SafeBrowsingPrivateEventRouter::kKeyDangerousDownloadEvent); + EXPECT_NE(nullptr, event); + EXPECT_EQ( + "/path/to/bypass.exe", + *event->FindStringKey(SafeBrowsingPrivateEventRouter::kKeyFileName)); + EXPECT_EQ("exe", *event->FindStringKey( + SafeBrowsingPrivateEventRouter::kKeyContentType)); + EXPECT_EQ( + 890, *event->FindIntKey(SafeBrowsingPrivateEventRouter::kKeyContentSize)); + EXPECT_EQ( + "BYPASSED_WARNING", + *event->FindStringKey(SafeBrowsingPrivateEventRouter::kKeyThreatType)); +} + TEST_F(SafeBrowsingPrivateEventRouterTest, PolicyControlOnToOffIsDynamic) { SetUpRouters(); SafeBrowsingEventObserver event_observer( diff --git a/chromium/chrome/browser/extensions/api/sessions/sessions_api.cc b/chromium/chrome/browser/extensions/api/sessions/sessions_api.cc index 882f22b3fdf..7d2d33e5188 100644 --- a/chromium/chrome/browser/extensions/api/sessions/sessions_api.cc +++ b/chromium/chrome/browser/extensions/api/sessions/sessions_api.cc @@ -104,10 +104,8 @@ api::tabs::Tab CreateTabModelHelper( ExtensionTabUtil::ScrubTabBehavior scrub_tab_behavior = ExtensionTabUtil::GetScrubTabBehavior(extension, context, url); - if (scrub_tab_behavior != ExtensionTabUtil::kDontScrubTab) { - ExtensionTabUtil::ScrubTabForExtension(extension, nullptr, &tab_struct, - scrub_tab_behavior); - } + ExtensionTabUtil::ScrubTabForExtension(extension, nullptr, &tab_struct, + scrub_tab_behavior); return tab_struct; } diff --git a/chromium/chrome/browser/extensions/api/sessions/sessions_apitest.cc b/chromium/chrome/browser/extensions/api/sessions/sessions_apitest.cc index f8fc80c5b23..4a84d88c33d 100644 --- a/chromium/chrome/browser/extensions/api/sessions/sessions_apitest.cc +++ b/chromium/chrome/browser/extensions/api/sessions/sessions_apitest.cc @@ -27,7 +27,7 @@ #include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/testing_browser_process.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/engine/data_type_activation_response.h" #include "components/sync/model/data_type_activation_request.h" #include "components/sync/model/model_type_controller_delegate.h" @@ -144,8 +144,9 @@ testing::AssertionResult CheckSessionModels(const base::ListValue& devices, return testing::AssertionSuccess(); } -std::string TagHashFromSpecifics(const sync_pb::SessionSpecifics& specifics) { - return syncer::GenerateSyncableHash( +syncer::ClientTagHash TagHashFromSpecifics( + const sync_pb::SessionSpecifics& specifics) { + return syncer::ClientTagHash::FromUnhashed( syncer::SESSIONS, sync_sessions::SessionStore::GetClientTag(specifics)); } @@ -236,7 +237,8 @@ void ExtensionSessionsTest::CreateSessionModels() { auto header_entity_data = std::make_unique<syncer::EntityData>(); header_entity_data->client_tag_hash = TagHashFromSpecifics(header_entity.session()); - header_entity_data->id = "FakeId:" + header_entity_data->client_tag_hash; + header_entity_data->id = + "FakeId:" + header_entity_data->client_tag_hash.value(); header_entity_data->specifics = header_entity; header_entity_data->creation_time = time_now - base::TimeDelta::FromSeconds(index); diff --git a/chromium/chrome/browser/extensions/api/settings_overrides/settings_overrides_api.cc b/chromium/chrome/browser/extensions/api/settings_overrides/settings_overrides_api.cc index 706e3a5b7ab..a9d7d9a853b 100644 --- a/chromium/chrome/browser/extensions/api/settings_overrides/settings_overrides_api.cc +++ b/chromium/chrome/browser/extensions/api/settings_overrides/settings_overrides_api.cc @@ -22,7 +22,6 @@ #include "components/search_engines/template_url_prepopulate_data.h" #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_prefs_factory.h" -#include "extensions/browser/extension_registry.h" #include "extensions/common/error_utils.h" #include "extensions/common/manifest_constants.h" @@ -110,8 +109,7 @@ std::unique_ptr<TemplateURLData> ConvertSearchProvider( SettingsOverridesAPI::SettingsOverridesAPI(content::BrowserContext* context) : profile_(Profile::FromBrowserContext(context)), - url_service_(TemplateURLServiceFactory::GetForProfile(profile_)), - extension_registry_observer_(this) { + url_service_(TemplateURLServiceFactory::GetForProfile(profile_)) { extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); } diff --git a/chromium/chrome/browser/extensions/api/settings_overrides/settings_overrides_api.h b/chromium/chrome/browser/extensions/api/settings_overrides/settings_overrides_api.h index 3c80f897680..baf7419ef7b 100644 --- a/chromium/chrome/browser/extensions/api/settings_overrides/settings_overrides_api.h +++ b/chromium/chrome/browser/extensions/api/settings_overrides/settings_overrides_api.h @@ -13,12 +13,12 @@ #include "base/scoped_observer.h" #include "components/search_engines/template_url_service.h" #include "extensions/browser/browser_context_keyed_api_factory.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry_observer.h" class Profile; namespace extensions { -class ExtensionRegistry; class SettingsOverridesAPI : public BrowserContextKeyedAPI, public ExtensionRegistryObserver { @@ -56,7 +56,7 @@ class SettingsOverridesAPI : public BrowserContextKeyedAPI, // Listen to extension load, unloaded notifications. ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - extension_registry_observer_; + extension_registry_observer_{this}; DISALLOW_COPY_AND_ASSIGN(SettingsOverridesAPI); }; diff --git a/chromium/chrome/browser/extensions/api/settings_private/chromeos_resolve_time_zone_by_geolocation_method_short.cc b/chromium/chrome/browser/extensions/api/settings_private/chromeos_resolve_time_zone_by_geolocation_method_short.cc index 65c4c99243e..18323cfb6a8 100644 --- a/chromium/chrome/browser/extensions/api/settings_private/chromeos_resolve_time_zone_by_geolocation_method_short.cc +++ b/chromium/chrome/browser/extensions/api/settings_private/chromeos_resolve_time_zone_by_geolocation_method_short.cc @@ -5,6 +5,7 @@ #include "chrome/browser/extensions/api/settings_private/chromeos_resolve_time_zone_by_geolocation_method_short.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/chromeos/system/timezone_resolver_manager.h" #include "chrome/browser/extensions/api/settings_private/generated_pref.h" #include "chrome/browser/extensions/api/settings_private/generated_time_zone_pref_base.h" diff --git a/chromium/chrome/browser/extensions/api/settings_private/chromeos_resolve_time_zone_by_geolocation_on_off.cc b/chromium/chrome/browser/extensions/api/settings_private/chromeos_resolve_time_zone_by_geolocation_on_off.cc index 4227609b7ab..3eec3a7ea37 100644 --- a/chromium/chrome/browser/extensions/api/settings_private/chromeos_resolve_time_zone_by_geolocation_on_off.cc +++ b/chromium/chrome/browser/extensions/api/settings_private/chromeos_resolve_time_zone_by_geolocation_on_off.cc @@ -6,6 +6,7 @@ #include "base/feature_list.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/chromeos/system/timezone_resolver_manager.h" #include "chrome/browser/extensions/api/settings_private/generated_pref.h" #include "chrome/browser/extensions/api/settings_private/generated_time_zone_pref_base.h" diff --git a/chromium/chrome/browser/extensions/api/settings_private/generated_time_zone_pref_base.cc b/chromium/chrome/browser/extensions/api/settings_private/generated_time_zone_pref_base.cc index 9e1dae7356f..92dd63b50f5 100644 --- a/chromium/chrome/browser/extensions/api/settings_private/generated_time_zone_pref_base.cc +++ b/chromium/chrome/browser/extensions/api/settings_private/generated_time_zone_pref_base.cc @@ -6,6 +6,7 @@ #include "base/feature_list.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/chromeos/system/timezone_resolver_manager.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/common/chrome_features.h" diff --git a/chromium/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chromium/chrome/browser/extensions/api/settings_private/prefs_util.cc index 40e299858d2..a4878a09ca6 100644 --- a/chromium/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chromium/chrome/browser/extensions/api/settings_private/prefs_util.cc @@ -8,6 +8,7 @@ #include "build/branding_buildflags.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/extensions/api/settings_private/generated_prefs.h" #include "chrome/browser/extensions/api/settings_private/generated_prefs_factory.h" #include "chrome/browser/extensions/chrome_extension_function.h" @@ -56,6 +57,7 @@ #include "chrome/browser/extensions/api/settings_private/chromeos_resolve_time_zone_by_geolocation_method_short.h" #include "chrome/browser/extensions/api/settings_private/chromeos_resolve_time_zone_by_geolocation_on_off.h" #include "chromeos/constants/chromeos_features.h" +#include "chromeos/constants/chromeos_pref_names.h" #include "chromeos/services/assistant/public/cpp/assistant_prefs.h" #include "chromeos/settings/cros_settings_names.h" #include "components/arc/arc_prefs.h" @@ -150,6 +152,8 @@ const PrefsUtil::TypedPrefMap& PrefsUtil::GetWhitelistedKeys() { settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_whitelist)[autofill::prefs::kAutofillCreditCardEnabled] = settings_api::PrefType::PREF_TYPE_BOOLEAN; + (*s_whitelist)[autofill::prefs::kAutofillCreditCardFidoAuthEnabled] = + settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_whitelist)[payments::kCanMakePaymentEnabled] = settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_whitelist)[bookmarks::prefs::kShowBookmarkBar] = @@ -344,6 +348,8 @@ const PrefsUtil::TypedPrefMap& PrefsUtil::GetWhitelistedKeys() { settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_whitelist)[chromeos::kAccountsPrefUsers] = settings_api::PrefType::PREF_TYPE_LIST; + (*s_whitelist)[chromeos::prefs::kSecondaryGoogleAccountSigninAllowed] = + settings_api::PrefType::PREF_TYPE_BOOLEAN; // kEnableAutoScreenLock is read-only. (*s_whitelist)[ash::prefs::kEnableAutoScreenLock] = settings_api::PrefType::PREF_TYPE_BOOLEAN; @@ -751,8 +757,13 @@ std::unique_ptr<settings_api::PrefObject> PrefsUtil::GetPref( #endif if (pref && pref->IsManaged()) { - pref_object->controlled_by = - settings_api::ControlledBy::CONTROLLED_BY_USER_POLICY; + if (profile_->IsChild()) { + pref_object->controlled_by = + settings_api::ControlledBy::CONTROLLED_BY_CHILD_RESTRICTION; + } else { + pref_object->controlled_by = + settings_api::ControlledBy::CONTROLLED_BY_USER_POLICY; + } pref_object->enforcement = settings_api::Enforcement::ENFORCEMENT_ENFORCED; return pref_object; } diff --git a/chromium/chrome/browser/extensions/api/settings_private/settings_private_delegate.cc b/chromium/chrome/browser/extensions/api/settings_private/settings_private_delegate.cc index 9eb362464dd..1c6eddf0231 100644 --- a/chromium/chrome/browser/extensions/api/settings_private/settings_private_delegate.cc +++ b/chromium/chrome/browser/extensions/api/settings_private/settings_private_delegate.cc @@ -15,9 +15,9 @@ #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" -#include "content/public/common/page_zoom.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h" +#include "third_party/blink/public/common/page/page_zoom.h" #include "url/gurl.h" namespace extensions { @@ -64,7 +64,7 @@ std::unique_ptr<base::Value> SettingsPrivateDelegate::GetDefaultZoom() { // default value. if (profile_->IsOffTheRecord()) return std::make_unique<base::Value>(0.0); - double zoom = content::ZoomLevelToZoomFactor( + double zoom = blink::PageZoomLevelToZoomFactor( profile_->GetZoomLevelPrefs()->GetDefaultZoomLevelPref()); return std::make_unique<base::Value>(zoom); } @@ -74,7 +74,7 @@ settings_private::SetPrefResult SettingsPrivateDelegate::SetDefaultZoom( // See comment in GetDefaultZoom(). if (profile_->IsOffTheRecord()) return settings_private::SetPrefResult::PREF_NOT_MODIFIABLE; - double zoom_factor = content::ZoomFactorToZoomLevel(zoom); + double zoom_factor = blink::PageZoomFactorToZoomLevel(zoom); profile_->GetZoomLevelPrefs()->SetDefaultZoomLevelPref(zoom_factor); return settings_private::SetPrefResult::SUCCESS; } diff --git a/chromium/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper_unittest.cc b/chromium/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper_unittest.cc index cdc749a01c9..e6460b930f1 100644 --- a/chromium/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper_unittest.cc +++ b/chromium/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper_unittest.cc @@ -33,13 +33,17 @@ TEST(IdMappingHelperTest, SetIdsForDevices) { devices.push_back(std::make_unique<DeviceInfo>( base::GenerateGUID(), "abc Device", "XYZ v1", "XYZ SyncAgent v1", - sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id1", base::Time(), - /*send_tab_to_self_receiving_enabled=*/true)); + sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id1", + base::SysInfo::HardwareInfo(), base::Time(), + /*send_tab_to_self_receiving_enabled=*/true, + /*sharing_info=*/base::nullopt)); devices.push_back(std::make_unique<DeviceInfo>( base::GenerateGUID(), "def Device", "XYZ v1", "XYZ SyncAgent v1", - sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id2", base::Time(), - /*send_tab_to_self_receiving_enabled=*/true)); + sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id2", + base::SysInfo::HardwareInfo(), base::Time(), + /*send_tab_to_self_receiving_enabled=*/true, + /*sharing_info=*/base::nullopt)); base::DictionaryValue dictionary; @@ -56,8 +60,10 @@ TEST(IdMappingHelperTest, SetIdsForDevices) { // Now add a third device. devices.push_back(std::make_unique<DeviceInfo>( base::GenerateGUID(), "ghi Device", "XYZ v1", "XYZ SyncAgent v1", - sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id3", base::Time(), - /*send_tab_to_self_receiving_enabled=*/true)); + sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id3", + base::SysInfo::HardwareInfo(), base::Time(), + /*send_tab_to_self_receiving_enabled=*/true, + /*sharing_info=*/base::nullopt)); CreateMappingForUnmappedDevices(devices, &dictionary); diff --git a/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc b/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc index 1d5d4eac138..0ebd0738031 100644 --- a/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc +++ b/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc @@ -18,16 +18,14 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/device_info_sync_service_factory.h" #include "components/sync_device_info/device_info.h" -#include "components/sync_device_info/device_info_sync_service.h" -#include "components/sync_device_info/fake_device_info_tracker.h" +#include "components/sync_device_info/fake_device_info_sync_service.h" #include "content/public/test/browser_task_environment.h" #include "extensions/common/extension.h" -#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" using syncer::DeviceInfo; +using syncer::FakeDeviceInfoSyncService; using syncer::FakeDeviceInfoTracker; -using testing::Return; namespace extensions { @@ -45,12 +43,16 @@ TEST(SignedInDevicesAPITest, GetSignedInDevices) { DeviceInfo device_info1(base::GenerateGUID(), "abc Device", "XYZ v1", "XYZ SyncAgent v1", sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id", - base::Time(), true); + base::SysInfo::HardwareInfo(), base::Time(), + /*send_tab_to_self_receiving_enabled=*/true, + /*sharing_info=*/base::nullopt); DeviceInfo device_info2(base::GenerateGUID(), "def Device", "XYZ v2", "XYZ SyncAgent v2", sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id", - base::Time(), true); + base::SysInfo::HardwareInfo(), base::Time(), + /*send_tab_to_self_receiving_enabled=*/true, + /*sharing_info=*/base::nullopt); device_tracker.Add(&device_info1); device_tracker.Add(&device_info2); @@ -70,7 +72,9 @@ TEST(SignedInDevicesAPITest, GetSignedInDevices) { DeviceInfo device_info3(base::GenerateGUID(), "def Device", "jkl v2", "XYZ SyncAgent v2", sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id", - base::Time(), true); + base::SysInfo::HardwareInfo(), base::Time(), + /*send_tab_to_self_receiving_enabled=*/true, + /*sharing_info=*/base::nullopt); device_tracker.Add(&device_info3); @@ -86,39 +90,16 @@ TEST(SignedInDevicesAPITest, GetSignedInDevices) { EXPECT_NE(public_id3, public_id2); } -class MockDeviceInfoSyncService : public syncer::DeviceInfoSyncService { - public: - MockDeviceInfoSyncService() = default; - ~MockDeviceInfoSyncService() override = default; - - FakeDeviceInfoTracker* fake_tracker() { return &tracker_; } - - // DeviceInfoSyncService implementation. - syncer::LocalDeviceInfoProvider* GetLocalDeviceInfoProvider() override { - return nullptr; - } - syncer::DeviceInfoTracker* GetDeviceInfoTracker() override { - return &tracker_; - } - base::WeakPtr<syncer::ModelTypeControllerDelegate> GetControllerDelegate() - override { - return nullptr; - } - - private: - FakeDeviceInfoTracker tracker_; -}; - -std::unique_ptr<KeyedService> CreateMockDeviceInfoSyncService( +std::unique_ptr<KeyedService> CreateFakeDeviceInfoSyncService( content::BrowserContext* context) { - return std::make_unique<MockDeviceInfoSyncService>(); + return std::make_unique<FakeDeviceInfoSyncService>(); } class ExtensionSignedInDevicesTest : public ExtensionApiUnittest { private: TestingProfile::TestingFactories GetTestingFactories() override { return {{DeviceInfoSyncServiceFactory::GetInstance(), - base::BindRepeating(&CreateMockDeviceInfoSyncService)}}; + base::BindRepeating(&CreateFakeDeviceInfoSyncService)}}; } }; @@ -151,20 +132,23 @@ base::DictionaryValue* GetDictionaryFromList(int index, } TEST_F(ExtensionSignedInDevicesTest, GetAll) { - FakeDeviceInfoTracker* device_tracker = - static_cast<MockDeviceInfoSyncService*>( - DeviceInfoSyncServiceFactory::GetForProfile(profile())) - ->fake_tracker(); + FakeDeviceInfoTracker* device_tracker = static_cast<FakeDeviceInfoTracker*>( + DeviceInfoSyncServiceFactory::GetForProfile(profile()) + ->GetDeviceInfoTracker()); DeviceInfo device_info1(base::GenerateGUID(), "abc Device", "XYZ v1", "XYZ SyncAgent v1", sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id", - base::Time(), true); + base::SysInfo::HardwareInfo(), base::Time(), + /*send_tab_to_self_receiving_enabled=*/true, + /*sharing_info=*/base::nullopt); DeviceInfo device_info2(base::GenerateGUID(), "def Device", "XYZ v2", "XYZ SyncAgent v2", sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id", - base::Time(), true); + base::SysInfo::HardwareInfo(), base::Time(), + /*send_tab_to_self_receiving_enabled=*/true, + /*sharing_info=*/base::nullopt); device_tracker->Add(&device_info1); device_tracker->Add(&device_info2); diff --git a/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc b/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc index 8b6576e9656..aa0cb34d1f1 100644 --- a/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc +++ b/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc @@ -19,7 +19,6 @@ #include "components/sync_device_info/device_info.h" #include "components/sync_device_info/device_info_sync_service.h" #include "extensions/browser/event_router.h" -#include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h" using syncer::DeviceInfo; @@ -93,13 +92,9 @@ SignedInDevicesManager::GetFactoryInstance() { return g_signed_in_devices_manager_factory.Pointer(); } -SignedInDevicesManager::SignedInDevicesManager() - : profile_(NULL), extension_registry_observer_(this) { -} - +SignedInDevicesManager::SignedInDevicesManager() = default; SignedInDevicesManager::SignedInDevicesManager(content::BrowserContext* context) - : profile_(Profile::FromBrowserContext(context)), - extension_registry_observer_(this) { + : profile_(Profile::FromBrowserContext(context)) { EventRouter* router = EventRouter::Get(profile_); if (router) { router->RegisterObserver( diff --git a/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.h b/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.h index bb7ab76b965..512d83d32fe 100644 --- a/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.h +++ b/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.h @@ -16,6 +16,7 @@ #include "content/public/browser/notification_registrar.h" #include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/event_router.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry_observer.h" class Profile; @@ -26,7 +27,6 @@ class BrowserContext; namespace extensions { class BrowserContextKeyedAPI; -class ExtensionRegistry; struct EventListenerInfo; @@ -54,6 +54,8 @@ class SignedInDevicesChangeObserver std::string extension_id_; Profile* const profile_; content::NotificationRegistrar registrar_; + + DISALLOW_COPY_AND_ASSIGN(SignedInDevicesChangeObserver); }; class SignedInDevicesManager : public BrowserContextKeyedAPI, @@ -90,12 +92,12 @@ class SignedInDevicesManager : public BrowserContextKeyedAPI, void RemoveChangeObserverForExtension(const std::string& extension_id); - Profile* const profile_; + Profile* const profile_ = nullptr; std::vector<std::unique_ptr<SignedInDevicesChangeObserver>> change_observers_; // Listen to extension unloaded notification. ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - extension_registry_observer_; + extension_registry_observer_{this}; FRIEND_TEST_ALL_PREFIXES(SignedInDevicesManager, UpdateListener); diff --git a/chromium/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc b/chromium/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc index 0e34dab6a97..49d784a90d7 100644 --- a/chromium/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc +++ b/chromium/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc @@ -12,6 +12,8 @@ #include "content/public/browser/browser_context.h" #include "content/public/test/test_storage_partition.h" #include "extensions/browser/api/socket/tcp_socket.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" #include "net/base/address_list.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" @@ -89,10 +91,10 @@ class TCPSocketUnitTestBase : public extensions::ExtensionServiceTestBase { void Initialize() { url_request_context_.Init(); network_context_ = std::make_unique<network::NetworkContext>( - nullptr, mojo::MakeRequest(&network_context_ptr_), + nullptr, network_context_remote_.BindNewPipeAndPassReceiver(), &url_request_context_, /*cors_exempt_header_list=*/std::vector<std::string>()); - partition_.set_network_context(network_context_ptr_.get()); + partition_.set_network_context(network_context_remote_.get()); } net::TestURLRequestContext url_request_context_; @@ -101,7 +103,7 @@ class TCPSocketUnitTestBase : public extensions::ExtensionServiceTestBase { TestingProfile profile_; content::TestStoragePartition partition_; std::unique_ptr<network::NetworkContext> network_context_; - network::mojom::NetworkContextPtr network_context_ptr_; + mojo::Remote<network::mojom::NetworkContext> network_context_remote_; }; } // namespace @@ -635,7 +637,9 @@ TEST_F(TCPSocketServerTest, ListenAccept) { base::RunLoop accept_run_loop; net::IPEndPoint accept_client_addr; socket->Accept(base::BindLambdaForTesting( - [&](int result, network::mojom::TCPConnectedSocketPtr accepted_socket, + [&](int result, + mojo::PendingRemote<network::mojom::TCPConnectedSocket> + accepted_socket, const base::Optional<net::IPEndPoint>& remote_addr, mojo::ScopedDataPipeConsumerHandle receive_handle, mojo::ScopedDataPipeProducerHandle send_handle) { @@ -690,7 +694,9 @@ TEST_F(TCPSocketServerTest, ReadAndWrite) { std::unique_ptr<TCPSocket> accepted_socket; socket->Accept(base::BindLambdaForTesting( - [&](int result, network::mojom::TCPConnectedSocketPtr connected_socket, + [&](int result, + mojo::PendingRemote<network::mojom::TCPConnectedSocket> + connected_socket, const base::Optional<net::IPEndPoint>& remote_addr, mojo::ScopedDataPipeConsumerHandle receive_handle, mojo::ScopedDataPipeProducerHandle send_handle) { diff --git a/chromium/chrome/browser/extensions/api/socket/tls_socket_unittest.cc b/chromium/chrome/browser/extensions/api/socket/tls_socket_unittest.cc index bab030e25d8..580a81c0d96 100644 --- a/chromium/chrome/browser/extensions/api/socket/tls_socket_unittest.cc +++ b/chromium/chrome/browser/extensions/api/socket/tls_socket_unittest.cc @@ -12,6 +12,8 @@ #include "content/public/browser/browser_context.h" #include "content/public/test/test_storage_partition.h" #include "extensions/browser/api/socket/tls_socket.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" #include "net/base/address_list.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" @@ -66,14 +68,16 @@ class TLSSocketTestBase : public extensions::ExtensionServiceTestBase { socket->UpgradeToTLS( nullptr /* options */, base::BindLambdaForTesting( - [&](int result, network::mojom::TLSClientSocketPtr tls_socket_ptr, + [&](int result, + mojo::PendingRemote<network::mojom::TLSClientSocket> + pending_tls_socket, const net::IPEndPoint& local_addr, const net::IPEndPoint& peer_addr, mojo::ScopedDataPipeConsumerHandle receive_handle, mojo::ScopedDataPipeProducerHandle send_handle) { if (net::OK == result) { tls_socket = std::make_unique<TLSSocket>( - std::move(tls_socket_ptr), local_addr, peer_addr, + std::move(pending_tls_socket), local_addr, peer_addr, std::move(receive_handle), std::move(send_handle), FAKE_ID); } run_loop.Quit(); @@ -89,10 +93,10 @@ class TLSSocketTestBase : public extensions::ExtensionServiceTestBase { void Initialize() { url_request_context_.Init(); network_context_ = std::make_unique<network::NetworkContext>( - nullptr, mojo::MakeRequest(&network_context_ptr_), + nullptr, network_context_remote_.BindNewPipeAndPassReceiver(), &url_request_context_, /*cors_exempt_header_list=*/std::vector<std::string>()); - partition_.set_network_context(network_context_ptr_.get()); + partition_.set_network_context(network_context_remote_.get()); } net::TestURLRequestContext url_request_context_; @@ -102,7 +106,7 @@ class TLSSocketTestBase : public extensions::ExtensionServiceTestBase { TestingProfile profile_; content::TestStoragePartition partition_; std::unique_ptr<network::NetworkContext> network_context_; - network::mojom::NetworkContextPtr network_context_ptr_; + mojo::Remote<network::mojom::NetworkContext> network_context_remote_; }; } // namespace @@ -170,12 +174,12 @@ TEST_F(TLSSocketTest, UpgradeToTLSWhilePendingRead) { auto socket = CreateTCPSocket(); // This read will be pending when UpgradeToTLS() is called. socket->Read(1 /* count */, base::DoNothing()); - network::mojom::TLSClientSocketPtr tls_socket_ptr; base::RunLoop run_loop; socket->UpgradeToTLS( nullptr /* options */, base::BindLambdaForTesting( - [&](int result, network::mojom::TLSClientSocketPtr tls_socket_ptr, + [&](int result, + mojo::PendingRemote<network::mojom::TLSClientSocket> tls_socket, const net::IPEndPoint& local_addr, const net::IPEndPoint& peer_addr, mojo::ScopedDataPipeConsumerHandle receive_handle, @@ -203,7 +207,6 @@ TEST_F(TLSSocketTest, UpgradeToTLSWithCustomOptions) { mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket); auto socket = CreateTCPSocket(); - network::mojom::TLSClientSocketPtr tls_socket_ptr; api::socket::SecureOptions options; options.tls_version = std::make_unique<api::socket::TLSVersionConstraints>(); options.tls_version->min = std::make_unique<std::string>("tls1.1"); @@ -213,7 +216,8 @@ TEST_F(TLSSocketTest, UpgradeToTLSWithCustomOptions) { socket->UpgradeToTLS( &options, base::BindLambdaForTesting( - [&](int result, network::mojom::TLSClientSocketPtr tls_socket_ptr, + [&](int result, + mojo::PendingRemote<network::mojom::TLSClientSocket> tls_socket, const net::IPEndPoint& local_addr, const net::IPEndPoint& peer_addr, mojo::ScopedDataPipeConsumerHandle receive_handle, @@ -244,7 +248,6 @@ TEST_F(TLSSocketTest, UpgradeToTLSWithCustomOptionsTLS13) { mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket); auto socket = CreateTCPSocket(); - network::mojom::TLSClientSocketPtr tls_socket_ptr; api::socket::SecureOptions options; options.tls_version = std::make_unique<api::socket::TLSVersionConstraints>(); options.tls_version->min = std::make_unique<std::string>("tls1.3"); @@ -254,7 +257,8 @@ TEST_F(TLSSocketTest, UpgradeToTLSWithCustomOptionsTLS13) { socket->UpgradeToTLS( &options, base::BindLambdaForTesting( - [&](int result, network::mojom::TLSClientSocketPtr tls_socket_ptr, + [&](int result, + mojo::PendingRemote<network::mojom::TLSClientSocket> tls_socket, const net::IPEndPoint& local_addr, const net::IPEndPoint& peer_addr, mojo::ScopedDataPipeConsumerHandle receive_handle, diff --git a/chromium/chrome/browser/extensions/api/socket/udp_socket_unittest.cc b/chromium/chrome/browser/extensions/api/socket/udp_socket_unittest.cc index 10356bc10a2..e25c6ddbf40 100644 --- a/chromium/chrome/browser/extensions/api/socket/udp_socket_unittest.cc +++ b/chromium/chrome/browser/extensions/api/socket/udp_socket_unittest.cc @@ -19,6 +19,8 @@ #include "chrome/test/base/browser_with_test_window_test.h" #include "content/public/browser/storage_partition.h" #include "extensions/browser/api/socket/udp_socket.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/io_buffer.h" #include "net/base/ip_address.h" #include "net/base/test_completion_callback.h" @@ -37,14 +39,15 @@ class UDPSocketUnitTest : public extensions::ExtensionServiceTestBase { network::mojom::NetworkContext* network_context = content::BrowserContext::GetDefaultStoragePartition(profile()) ->GetNetworkContext(); - network::mojom::UDPSocketPtrInfo socket; - network::mojom::UDPSocketListenerPtr listener_ptr; - network::mojom::UDPSocketListenerRequest listener_request = - mojo::MakeRequest(&listener_ptr); - network_context->CreateUDPSocket(mojo::MakeRequest(&socket), - std::move(listener_ptr)); - return std::make_unique<UDPSocket>( - std::move(socket), std::move(listener_request), "abcdefghijklmnopqrst"); + mojo::PendingRemote<network::mojom::UDPSocket> socket; + mojo::PendingRemote<network::mojom::UDPSocketListener> listener_remote; + mojo::PendingReceiver<network::mojom::UDPSocketListener> listener_receiver = + listener_remote.InitWithNewPipeAndPassReceiver(); + network_context->CreateUDPSocket(socket.InitWithNewPipeAndPassReceiver(), + std::move(listener_remote)); + return std::make_unique<UDPSocket>(std::move(socket), + std::move(listener_receiver), + "abcdefghijklmnopqrst"); } }; diff --git a/chromium/chrome/browser/extensions/api/spellcheck/spellcheck_api.cc b/chromium/chrome/browser/extensions/api/spellcheck/spellcheck_api.cc index 2605ca7cca4..0ba0c2d1008 100644 --- a/chromium/chrome/browser/extensions/api/spellcheck/spellcheck_api.cc +++ b/chromium/chrome/browser/extensions/api/spellcheck/spellcheck_api.cc @@ -8,7 +8,6 @@ #include "chrome/browser/spellchecker/spellcheck_factory.h" #include "chrome/browser/spellchecker/spellcheck_service.h" #include "chrome/common/extensions/api/spellcheck/spellcheck_handler.h" -#include "extensions/browser/extension_registry.h" #include "extensions/common/manifest_constants.h" namespace extensions { @@ -36,13 +35,11 @@ SpellcheckService::DictionaryFormat GetDictionaryFormat( } // namespace -SpellcheckAPI::SpellcheckAPI(content::BrowserContext* context) - : extension_registry_observer_(this) { +SpellcheckAPI::SpellcheckAPI(content::BrowserContext* context) { extension_registry_observer_.Add(ExtensionRegistry::Get(context)); } -SpellcheckAPI::~SpellcheckAPI() { -} +SpellcheckAPI::~SpellcheckAPI() = default; static base::LazyInstance<BrowserContextKeyedAPIFactory<SpellcheckAPI>>:: DestructorAtExit g_spellcheck_api_factory = LAZY_INSTANCE_INITIALIZER; diff --git a/chromium/chrome/browser/extensions/api/spellcheck/spellcheck_api.h b/chromium/chrome/browser/extensions/api/spellcheck/spellcheck_api.h index 71ed27ad628..b75884c6f62 100644 --- a/chromium/chrome/browser/extensions/api/spellcheck/spellcheck_api.h +++ b/chromium/chrome/browser/extensions/api/spellcheck/spellcheck_api.h @@ -8,10 +8,10 @@ #include "base/macros.h" #include "base/scoped_observer.h" #include "extensions/browser/browser_context_keyed_api_factory.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry_observer.h" namespace extensions { -class ExtensionRegistry; class SpellcheckAPI : public BrowserContextKeyedAPI, public ExtensionRegistryObserver { @@ -39,7 +39,7 @@ class SpellcheckAPI : public BrowserContextKeyedAPI, // Listen to extension load, unloaded notifications. ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - extension_registry_observer_; + extension_registry_observer_{this}; DISALLOW_COPY_AND_ASSIGN(SpellcheckAPI); }; diff --git a/chromium/chrome/browser/extensions/api/storage/managed_value_store_cache.cc b/chromium/chrome/browser/extensions/api/storage/managed_value_store_cache.cc index 91b42ede413..13344e45ef8 100644 --- a/chromium/chrome/browser/extensions/api/storage/managed_value_store_cache.cc +++ b/chromium/chrome/browser/extensions/api/storage/managed_value_store_cache.cc @@ -99,7 +99,7 @@ class ManagedValueStoreCache::ExtensionTracker Profile* profile_; policy::PolicyDomain policy_domain_; ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - extension_registry_observer_; + extension_registry_observer_{this}; policy::SchemaRegistry* schema_registry_; base::WeakPtrFactory<ExtensionTracker> weak_factory_{this}; @@ -111,7 +111,6 @@ ManagedValueStoreCache::ExtensionTracker::ExtensionTracker( policy::PolicyDomain policy_domain) : profile_(profile), policy_domain_(policy_domain), - extension_registry_observer_(this), schema_registry_(profile->GetPolicySchemaRegistryService()->registry()) { extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); // Load schemas when the extension system is ready. It might be ready now. diff --git a/chromium/chrome/browser/extensions/api/storage/settings_sync_unittest.cc b/chromium/chrome/browser/extensions/api/storage/settings_sync_unittest.cc index 12638792609..26678d70605 100644 --- a/chromium/chrome/browser/extensions/api/storage/settings_sync_unittest.cc +++ b/chromium/chrome/browser/extensions/api/storage/settings_sync_unittest.cc @@ -184,6 +184,8 @@ class ExtensionSettingsSyncTest : public testing::Test { void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); profile_.reset(new TestingProfile(temp_dir_.GetPath())); + content::RunAllTasksUntilIdle(); + storage_factory_->Reset(); frontend_ = StorageFrontend::CreateForTesting(storage_factory_, profile_.get()); diff --git a/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc index 926161b9923..6d8f4bc0eb0 100644 --- a/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc +++ b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc @@ -18,7 +18,6 @@ #include "content/public/browser/web_contents.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_icon_image.h" -#include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h" #include "extensions/common/extension_icon_set.h" @@ -141,9 +140,7 @@ SystemIndicatorManager::SystemIndicator::~SystemIndicator() = default; SystemIndicatorManager::SystemIndicatorManager(Profile* profile, StatusTray* status_tray) - : profile_(profile), - status_tray_(status_tray), - extension_registry_observer_(this) { + : profile_(profile), status_tray_(status_tray) { extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); } diff --git a/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager.h b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager.h index 378cc6a5796..4055d018928 100644 --- a/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager.h +++ b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager.h @@ -13,6 +13,7 @@ #include "base/scoped_observer.h" #include "base/threading/thread_checker.h" #include "components/keyed_service/core/keyed_service.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry_observer.h" #include "extensions/common/extension_icon_set.h" #include "extensions/common/extension_id.h" @@ -25,7 +26,6 @@ namespace extensions { FORWARD_DECLARE_TEST(SystemIndicatorApiTest, SystemIndicatorUnloaded); class ExtensionIndicatorIcon; -class ExtensionRegistry; // Keeps track of all the systemIndicator icons created for a given Profile // that are currently visible in the UI. Use SystemIndicatorManagerFactory to @@ -86,7 +86,7 @@ class SystemIndicatorManager : public ExtensionRegistryObserver, base::ThreadChecker thread_checker_; ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - extension_registry_observer_; + extension_registry_observer_{this}; DISALLOW_COPY_AND_ASSIGN(SystemIndicatorManager); }; diff --git a/chromium/chrome/browser/extensions/api/system_private/system_private_api.cc b/chromium/chrome/browser/extensions/api/system_private/system_private_api.cc index 99b8663476b..a6571765205 100644 --- a/chromium/chrome/browser/extensions/api/system_private/system_private_api.cc +++ b/chromium/chrome/browser/extensions/api/system_private/system_private_api.cc @@ -71,46 +71,49 @@ ExtensionFunction::ResponseAction SystemPrivateGetUpdateStatusFunction::Run() { #if defined(OS_CHROMEOS) // With UpdateEngineClient, we can provide more detailed information about // system updates on ChromeOS. - const chromeos::UpdateEngineClient::Status status = - chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()-> - GetLastStatus(); + const update_engine::StatusResult status = chromeos::DBusThreadManager::Get() + ->GetUpdateEngineClient() + ->GetLastStatus(); // |download_progress| is set to 1 after download finishes // (i.e. verify, finalize and need-reboot phase) to indicate the progress // even though |status.download_progress| is 0 in these phases. - switch (status.status) { - case chromeos::UpdateEngineClient::UPDATE_STATUS_ERROR: + switch (status.current_operation()) { + case update_engine::Operation::ERROR: + case update_engine::Operation::DISABLED: state = kNotAvailableState; break; - case chromeos::UpdateEngineClient::UPDATE_STATUS_IDLE: + case update_engine::Operation::IDLE: state = kNotAvailableState; break; - case chromeos::UpdateEngineClient::UPDATE_STATUS_CHECKING_FOR_UPDATE: + case update_engine::Operation::CHECKING_FOR_UPDATE: state = kNotAvailableState; break; - case chromeos::UpdateEngineClient::UPDATE_STATUS_UPDATE_AVAILABLE: + case update_engine::Operation::UPDATE_AVAILABLE: state = kUpdatingState; break; - case chromeos::UpdateEngineClient::UPDATE_STATUS_DOWNLOADING: + case update_engine::Operation::DOWNLOADING: state = kUpdatingState; - download_progress = status.download_progress; + download_progress = status.progress(); break; - case chromeos::UpdateEngineClient::UPDATE_STATUS_VERIFYING: + case update_engine::Operation::VERIFYING: state = kUpdatingState; download_progress = 1; break; - case chromeos::UpdateEngineClient::UPDATE_STATUS_FINALIZING: + case update_engine::Operation::FINALIZING: state = kUpdatingState; download_progress = 1; break; - case chromeos::UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT: + case update_engine::Operation::UPDATED_NEED_REBOOT: state = kNeedRestartState; download_progress = 1; break; - case chromeos::UpdateEngineClient::UPDATE_STATUS_REPORTING_ERROR_EVENT: - case chromeos::UpdateEngineClient::UPDATE_STATUS_ATTEMPTING_ROLLBACK: - case chromeos::UpdateEngineClient::UPDATE_STATUS_NEED_PERMISSION_TO_UPDATE: + case update_engine::Operation::REPORTING_ERROR_EVENT: + case update_engine::Operation::ATTEMPTING_ROLLBACK: + case update_engine::Operation::NEED_PERMISSION_TO_UPDATE: state = kNotAvailableState; break; + default: + NOTREACHED(); } #else if (UpgradeDetector::GetInstance()->notify_upgrade()) { diff --git a/chromium/chrome/browser/extensions/api/system_private/system_private_apitest.cc b/chromium/chrome/browser/extensions/api/system_private/system_private_apitest.cc index 6f14af16ebc..c2f658bc796 100644 --- a/chromium/chrome/browser/extensions/api/system_private/system_private_apitest.cc +++ b/chromium/chrome/browser/extensions/api/system_private/system_private_apitest.cc @@ -52,14 +52,14 @@ class GetUpdateStatusApiTest : public ExtensionApiTest { }; IN_PROC_BROWSER_TEST_F(GetUpdateStatusApiTest, Progress) { - UpdateEngineClient::Status status_not_available; - status_not_available.status = UpdateEngineClient::UPDATE_STATUS_IDLE; - UpdateEngineClient::Status status_updating; - status_updating.status = UpdateEngineClient::UPDATE_STATUS_DOWNLOADING; - status_updating.download_progress = 0.5; - UpdateEngineClient::Status status_boot_needed; - status_boot_needed.status = - UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT; + update_engine::StatusResult status_not_available; + status_not_available.set_current_operation(update_engine::Operation::IDLE); + update_engine::StatusResult status_updating; + status_updating.set_current_operation(update_engine::Operation::DOWNLOADING); + status_updating.set_progress(0.5); + update_engine::StatusResult status_boot_needed; + status_boot_needed.set_current_operation( + update_engine::Operation::UPDATED_NEED_REBOOT); // The fake client returns the last status in this order. fake_update_engine_client_->PushLastStatus(status_not_available); diff --git a/chromium/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc b/chromium/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc index 414887222cd..8be2cd77dc9 100644 --- a/chromium/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc +++ b/chromium/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc @@ -30,6 +30,7 @@ #include "extensions/common/switches.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" +#include "testing/gmock/include/gmock/gmock.h" namespace extensions { @@ -417,33 +418,23 @@ IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_Constraints) { #endif // Tests that the tab indicator (in the tab strip) is shown during tab capture. IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_TabIndicator) { - ASSERT_EQ(TabAlertState::NONE, - chrome::GetTabAlertStateForContents( - browser()->tab_strip_model()->GetActiveWebContents())); + content::WebContents* const contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_THAT(chrome::GetTabAlertStatesForContents(contents), + ::testing::IsEmpty()); - // A TabStripModelObserver that quits the MessageLoop whenever the UI's model - // is sent an event that changes the indicator status. + // A TabStripModelObserver that quits the MessageLoop whenever the + // UI's model is sent an event that might change the indicator status. class IndicatorChangeObserver : public TabStripModelObserver { public: - explicit IndicatorChangeObserver(Browser* browser) - : browser_(browser), - last_alert_state_(chrome::GetTabAlertStateForContents( - browser->tab_strip_model()->GetActiveWebContents())) { + explicit IndicatorChangeObserver(Browser* browser) : browser_(browser) { browser_->tab_strip_model()->AddObserver(this); } - TabAlertState last_alert_state() const { return last_alert_state_; } - void TabChangedAt(content::WebContents* contents, int index, TabChangeType change_type) override { - const TabAlertState alert_state = - chrome::GetTabAlertStateForContents(contents); - if (alert_state != last_alert_state_) { - last_alert_state_ = alert_state; - if (on_tab_changed_) - std::move(on_tab_changed_).Run(); - } + std::move(on_tab_changed_).Run(); } void WaitForTabChange() { @@ -454,12 +445,11 @@ IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_TabIndicator) { private: Browser* const browser_; - TabAlertState last_alert_state_; base::OnceClosure on_tab_changed_; }; - IndicatorChangeObserver observer(browser()); - ASSERT_EQ(TabAlertState::NONE, observer.last_alert_state()); + ASSERT_THAT(chrome::GetTabAlertStatesForContents(contents), + ::testing::IsEmpty()); // Run an extension test that just turns on tab capture, which should cause // the indicator to turn on. @@ -469,10 +459,13 @@ IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_TabIndicator) { // Run the browser until the indicator turns on. const base::TimeTicks start_time = base::TimeTicks::Now(); - while (observer.last_alert_state() != TabAlertState::TAB_CAPTURING) { + IndicatorChangeObserver observer(browser()); + while (!base::Contains(chrome::GetTabAlertStatesForContents(contents), + TabAlertState::TAB_CAPTURING)) { if (base::TimeTicks::Now() - start_time > TestTimeouts::action_max_timeout()) { - EXPECT_EQ(TabAlertState::TAB_CAPTURING, observer.last_alert_state()); + EXPECT_THAT(chrome::GetTabAlertStatesForContents(contents), + ::testing::Contains(TabAlertState::TAB_CAPTURING)); return; } observer.WaitForTabChange(); diff --git a/chromium/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc b/chromium/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc index 9a140c10ead..82a0c898096 100644 --- a/chromium/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc +++ b/chromium/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc @@ -19,8 +19,8 @@ #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" #include "extensions/browser/event_router.h" -#include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h" +#include "url/origin.h" using content::BrowserThread; using extensions::tab_capture::TabCaptureState; @@ -57,18 +57,10 @@ class TabCaptureRegistry::LiveRequest : public content::WebContentsObserver { ~LiveRequest() override {} // Accessors. - const std::string& extension_id() const { - return extension_id_; - } - bool is_anonymous() const { - return is_anonymous_; - } - TabCaptureState capture_state() const { - return capture_state_; - } - bool is_verified() const { - return is_verified_; - } + const std::string& extension_id() const { return extension_id_; } + bool is_anonymous() const { return is_anonymous_; } + TabCaptureState capture_state() const { return capture_state_; } + bool is_verified() const { return is_verified_; } void SetIsVerified() { DCHECK(!is_verified_); @@ -78,7 +70,7 @@ class TabCaptureRegistry::LiveRequest : public content::WebContentsObserver { bool WasTargettingRenderFrameID(int render_process_id, int render_frame_id) const { return render_process_id_ == render_process_id && - render_frame_id_ == render_frame_id; + render_frame_id_ == render_frame_id; } void UpdateCaptureState(TabCaptureState next_capture_state) { @@ -140,7 +132,7 @@ class TabCaptureRegistry::LiveRequest : public content::WebContentsObserver { }; TabCaptureRegistry::TabCaptureRegistry(content::BrowserContext* context) - : browser_context_(context), extension_registry_observer_(this) { + : browser_context_(context) { MediaCaptureDevicesDispatcher::GetInstance()->AddObserver(this); extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); } @@ -221,17 +213,17 @@ std::string TabCaptureRegistry::AddRequest( content::RenderFrameHost* const main_frame = caller_contents->GetMainFrame(); if (main_frame) { device_id = content::DesktopStreamsRegistry::GetInstance()->RegisterStream( - main_frame->GetProcess()->GetID(), main_frame->GetRoutingID(), origin, - source, extension_name, content::kRegistryStreamTypeTab); + main_frame->GetProcess()->GetID(), main_frame->GetRoutingID(), + url::Origin::Create(origin), source, extension_name, + content::kRegistryStreamTypeTab); } return device_id; } -bool TabCaptureRegistry::VerifyRequest( - int render_process_id, - int render_frame_id, - const std::string& extension_id) { +bool TabCaptureRegistry::VerifyRequest(int render_process_id, + int render_frame_id, + const std::string& extension_id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); LiveRequest* const request = FindRequest(render_process_id, render_frame_id); @@ -262,7 +254,7 @@ void TabCaptureRegistry::OnRequestUpdate( LiveRequest* request = FindRequest(target_render_process_id, target_render_frame_id); if (!request) { - return; // Stale or invalid request update. + return; // Stale or invalid request update. } TabCaptureState next_state = tab_capture::TAB_CAPTURE_STATE_NONE; diff --git a/chromium/chrome/browser/extensions/api/tab_capture/tab_capture_registry.h b/chromium/chrome/browser/extensions/api/tab_capture/tab_capture_registry.h index 5f02c884095..586d8949b21 100644 --- a/chromium/chrome/browser/extensions/api/tab_capture/tab_capture_registry.h +++ b/chromium/chrome/browser/extensions/api/tab_capture/tab_capture_registry.h @@ -16,6 +16,7 @@ #include "content/public/browser/desktop_media_id.h" #include "content/public/browser/media_request_state.h" #include "extensions/browser/browser_context_keyed_api_factory.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry_observer.h" namespace base { @@ -29,8 +30,6 @@ class WebContents; namespace extensions { -class ExtensionRegistry; - namespace tab_capture = api::tab_capture; class TabCaptureRegistry : public BrowserContextKeyedAPI, @@ -118,7 +117,7 @@ class TabCaptureRegistry : public BrowserContextKeyedAPI, std::vector<std::unique_ptr<LiveRequest>> requests_; ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - extension_registry_observer_; + extension_registry_observer_{this}; DISALLOW_COPY_AND_ASSIGN(TabCaptureRegistry); }; diff --git a/chromium/chrome/browser/extensions/api/tabs/tabs_api.cc b/chromium/chrome/browser/extensions/api/tabs/tabs_api.cc index 874af5d556c..07871d23ce0 100644 --- a/chromium/chrome/browser/extensions/api/tabs/tabs_api.cc +++ b/chromium/chrome/browser/extensions/api/tabs/tabs_api.cc @@ -92,6 +92,7 @@ #include "net/base/escape.h" #include "skia/ext/image_operations.h" #include "skia/ext/platform_canvas.h" +#include "third_party/blink/public/common/page/page_zoom.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/models/list_selection_model.h" #include "ui/base/ui_base_types.h" @@ -1357,15 +1358,13 @@ bool TabsUpdateFunction::UpdateURL(const std::string& url_string, NavigationController::LoadURLParams load_params(url); - // For the PDF extension, treat it as renderer-initiated so that it does not - // show in the omnibox until it commits. This avoids URL spoofs since urls - // can be opened on behalf of untrusted content. - // TODO(devlin|nasko): Make this the default for all extensions. - if (extension() && extension()->id() == extension_misc::kPdfExtensionId) { - load_params.is_renderer_initiated = true; - load_params.initiator_origin = url::Origin::Create( - Extension::GetBaseURLFromExtensionId(extension()->id())); - } + // Treat extension-initiated navigations as renderer-initiated so that the URL + // does not show in the omnibox until it commits. This avoids URL spoofs + // since URLs can be opened on behalf of untrusted content. + load_params.is_renderer_initiated = true; + load_params.initiator_origin = url::Origin::Create( + Extension::GetBaseURLFromExtensionId(extension()->id())); + web_contents_->GetController().LoadURLWithParams(load_params); DCHECK_EQ(url, @@ -1999,9 +1998,10 @@ ExtensionFunction::ResponseAction TabsSetZoomFunction::Run() { ZoomController* zoom_controller = ZoomController::FromWebContents(web_contents); - double zoom_level = params->zoom_factor > 0 - ? content::ZoomFactorToZoomLevel(params->zoom_factor) - : zoom_controller->GetDefaultZoomLevel(); + double zoom_level = + params->zoom_factor > 0 + ? blink::PageZoomFactorToZoomLevel(params->zoom_factor) + : zoom_controller->GetDefaultZoomLevel(); auto client = base::MakeRefCounted<ExtensionZoomRequestClient>(extension()); if (!zoom_controller->SetZoomLevelByClient(zoom_level, client)) { @@ -2026,7 +2026,7 @@ ExtensionFunction::ResponseAction TabsGetZoomFunction::Run() { double zoom_level = ZoomController::FromWebContents(web_contents)->GetZoomLevel(); - double zoom_factor = content::ZoomLevelToZoomFactor(zoom_level); + double zoom_factor = blink::PageZoomLevelToZoomFactor(zoom_level); return RespondNow(ArgumentList(tabs::GetZoom::Results::Create(zoom_factor))); } @@ -2100,8 +2100,9 @@ ExtensionFunction::ResponseAction TabsGetZoomSettingsFunction::Run() { ZoomController::ZoomMode zoom_mode = zoom_controller->zoom_mode(); api::tabs::ZoomSettings zoom_settings; ZoomModeToZoomSettings(zoom_mode, &zoom_settings); - zoom_settings.default_zoom_factor.reset(new double( - content::ZoomLevelToZoomFactor(zoom_controller->GetDefaultZoomLevel()))); + zoom_settings.default_zoom_factor.reset( + new double(blink::PageZoomLevelToZoomFactor( + zoom_controller->GetDefaultZoomLevel()))); return RespondNow( ArgumentList(api::tabs::GetZoomSettings::Results::Create(zoom_settings))); diff --git a/chromium/chrome/browser/extensions/api/tabs/tabs_constants.cc b/chromium/chrome/browser/extensions/api/tabs/tabs_constants.cc index ed8ab5f7f37..751330613c9 100644 --- a/chromium/chrome/browser/extensions/api/tabs/tabs_constants.cc +++ b/chromium/chrome/browser/extensions/api/tabs/tabs_constants.cc @@ -48,6 +48,7 @@ const char kTitleKey[] = "title"; const char kToIndexKey[] = "toIndex"; const char kTopKey[] = "top"; const char kUrlKey[] = "url"; +const char kPendingUrlKey[] = "pendingUrl"; const char kWindowClosing[] = "isWindowClosing"; const char kWidthKey[] = "width"; const char kWindowIdKey[] = "windowId"; diff --git a/chromium/chrome/browser/extensions/api/tabs/tabs_constants.h b/chromium/chrome/browser/extensions/api/tabs/tabs_constants.h index a58d60121a3..968b0abf313 100644 --- a/chromium/chrome/browser/extensions/api/tabs/tabs_constants.h +++ b/chromium/chrome/browser/extensions/api/tabs/tabs_constants.h @@ -52,6 +52,7 @@ extern const char kTitleKey[]; extern const char kToIndexKey[]; extern const char kTopKey[]; extern const char kUrlKey[]; +extern const char kPendingUrlKey[]; extern const char kWidthKey[]; extern const char kWindowClosing[]; extern const char kWindowIdKey[]; diff --git a/chromium/chrome/browser/extensions/api/tabs/tabs_event_router.cc b/chromium/chrome/browser/extensions/api/tabs/tabs_event_router.cc index f86ebb9b063..402d3de9620 100644 --- a/chromium/chrome/browser/extensions/api/tabs/tabs_event_router.cc +++ b/chromium/chrome/browser/extensions/api/tabs/tabs_event_router.cc @@ -28,6 +28,7 @@ #include "content/public/browser/navigation_entry.h" #include "content/public/browser/web_contents.h" #include "extensions/common/features/feature.h" +#include "third_party/blink/public/common/page/page_zoom.h" using base::DictionaryValue; using base::ListValue; @@ -162,10 +163,7 @@ void TabsEventRouter::TabEntry::WebContentsDestroyed() { } TabsEventRouter::TabsEventRouter(Profile* profile) - : profile_(profile), - favicon_scoped_observer_(this), - browser_tab_strip_tracker_(this, this, this), - tab_manager_scoped_observer_(this) { + : profile_(profile), browser_tab_strip_tracker_(this, this, this) { DCHECK(!profile->IsOffTheRecord()); browser_tab_strip_tracker_.Init(); @@ -275,9 +273,9 @@ void TabsEventRouter::OnZoomChanged( api::tabs::OnZoomChange::ZoomChangeInfo zoom_change_info; zoom_change_info.tab_id = tab_id; zoom_change_info.old_zoom_factor = - content::ZoomLevelToZoomFactor(data.old_zoom_level); + blink::PageZoomLevelToZoomFactor(data.old_zoom_level); zoom_change_info.new_zoom_factor = - content::ZoomLevelToZoomFactor(data.new_zoom_level); + blink::PageZoomLevelToZoomFactor(data.new_zoom_level); ZoomModeToZoomSettings(data.zoom_mode, &zoom_change_info.zoom_settings); // Dispatch the |onZoomChange| event. diff --git a/chromium/chrome/browser/extensions/api/tabs/tabs_event_router.h b/chromium/chrome/browser/extensions/api/tabs/tabs_event_router.h index 14f37b6f537..e7335a902ae 100644 --- a/chromium/chrome/browser/extensions/api/tabs/tabs_event_router.h +++ b/chromium/chrome/browser/extensions/api/tabs/tabs_event_router.h @@ -18,6 +18,7 @@ #include "chrome/browser/ui/browser_tab_strip_tracker.h" #include "chrome/browser/ui/browser_tab_strip_tracker_delegate.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" +#include "components/favicon/core/favicon_driver.h" #include "components/favicon/core/favicon_driver_observer.h" #include "components/zoom/zoom_observer.h" #include "content/public/browser/web_contents_observer.h" @@ -27,10 +28,6 @@ namespace content { class WebContents; } -namespace favicon { -class FaviconDriver; -} - namespace extensions { // The TabsEventRouter listens to tab events and routes them to listeners inside @@ -205,13 +202,14 @@ class TabsEventRouter : public TabStripModelObserver, // The main profile that owns this event router. Profile* profile_; - ScopedObserver<favicon::FaviconDriver, TabsEventRouter> - favicon_scoped_observer_; + ScopedObserver<favicon::FaviconDriver, favicon::FaviconDriverObserver> + favicon_scoped_observer_{this}; BrowserTabStripTracker browser_tab_strip_tracker_; - ScopedObserver<resource_coordinator::TabManager, TabsEventRouter> - tab_manager_scoped_observer_; + ScopedObserver<resource_coordinator::TabManager, + resource_coordinator::TabLifecycleObserver> + tab_manager_scoped_observer_{this}; DISALLOW_COPY_AND_ASSIGN(TabsEventRouter); }; diff --git a/chromium/chrome/browser/extensions/api/tabs/tabs_test.cc b/chromium/chrome/browser/extensions/api/tabs/tabs_test.cc index f5fb14246df..e908335e12f 100644 --- a/chromium/chrome/browser/extensions/api/tabs/tabs_test.cc +++ b/chromium/chrome/browser/extensions/api/tabs/tabs_test.cc @@ -48,7 +48,6 @@ #include "content/public/browser/render_frame_host.h" #include "content/public/browser/storage_partition.h" #include "content/public/common/mime_handler_view_mode.h" -#include "content/public/common/page_zoom.h" #include "content/public/common/url_constants.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_navigation_observer.h" @@ -61,6 +60,7 @@ #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "third_party/blink/public/common/page/page_zoom.h" #include "ui/base/window_open_disposition.h" #include "ui/gfx/geometry/rect.h" #include "ui/views/widget/widget.h" @@ -98,6 +98,8 @@ class ExtensionWindowCreateTest : public InProcessBrowserTest { }; const int kUndefinedId = INT_MIN; +const ExtensionTabUtil::ScrubTabBehavior kDontScrubBehavior = { + ExtensionTabUtil::kDontScrubTab, ExtensionTabUtil::kDontScrubTab}; int GetTabId(base::DictionaryValue* tab) { int id = kUndefinedId; @@ -1136,9 +1138,9 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, DuplicateTab) { EXPECT_EQ(window_id, duplicate_tab_window_id); EXPECT_EQ(tab_index + 1, duplicate_tab_index); // The test empty tab extension has tabs permissions, therefore - // |duplicate_result| should contain url, title, and faviconUrl + // |duplicate_result| should contain url, pendingUrl, title or faviconUrl // in the function result. - EXPECT_TRUE(utils::HasPrivacySensitiveFields(duplicate_result.get())); + EXPECT_TRUE(utils::HasAnyPrivacySensitiveFields(duplicate_result.get())); } IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, DuplicateTabNoPermission) { @@ -1174,8 +1176,9 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, DuplicateTabNoPermission) { EXPECT_EQ(window_id, duplicate_tab_window_id); EXPECT_EQ(tab_index + 1, duplicate_tab_index); // The test empty extension has no permissions, therefore |duplicate_result| - // should not contain url, title, and faviconUrl in the function result. - EXPECT_FALSE(utils::HasPrivacySensitiveFields(duplicate_result.get())); + // should not contain url, pendingUrl, title and faviconUrl in the function + // result. + EXPECT_FALSE(utils::HasAnyPrivacySensitiveFields(duplicate_result.get())); } IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, NoTabsEventOnDevTools) { @@ -1323,8 +1326,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, DiscardedProperty) { // Creates Tab object to ensure the property is correct for the extension. std::unique_ptr<api::tabs::Tab> tab_object_a = - ExtensionTabUtil::CreateTabObject(web_contents_a, - ExtensionTabUtil::kDontScrubTab, + ExtensionTabUtil::CreateTabObject(web_contents_a, kDontScrubBehavior, nullptr, tab_strip_model, 0); EXPECT_FALSE(tab_object_a->discarded); @@ -1334,8 +1336,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, DiscardedProperty) { // Make sure the property is changed accordingly after discarding the tab. tab_object_a = ExtensionTabUtil::CreateTabObject( - web_contents_a, ExtensionTabUtil::kDontScrubTab, nullptr, tab_strip_model, - 0); + web_contents_a, kDontScrubBehavior, nullptr, tab_strip_model, 0); EXPECT_TRUE(tab_object_a->discarded); // Get non-discarded tabs after discarding one tab. @@ -1530,8 +1531,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, AutoDiscardableProperty) { // Creates Tab object to ensure the property is correct for the extension. TabStripModel* tab_strip_model = browser()->tab_strip_model(); std::unique_ptr<api::tabs::Tab> tab_object_a = - ExtensionTabUtil::CreateTabObject(web_contents_a, - ExtensionTabUtil::kDontScrubTab, + ExtensionTabUtil::CreateTabObject(web_contents_a, kDontScrubBehavior, nullptr, tab_strip_model, 0); EXPECT_TRUE(tab_object_a->auto_discardable); @@ -1575,8 +1575,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, AutoDiscardableProperty) { // Make sure the property is changed accordingly after updating the tab. tab_object_a = ExtensionTabUtil::CreateTabObject( - web_contents_a, ExtensionTabUtil::kDontScrubTab, nullptr, tab_strip_model, - 0); + web_contents_a, kDontScrubBehavior, nullptr, tab_strip_model, 0); EXPECT_FALSE(tab_object_a->auto_discardable); // Get auto-discardable tabs after changing the status of web contents A. @@ -1847,7 +1846,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest, SetAndGetZoom) { const double kZoomLevel = 0.8; EXPECT_TRUE(RunSetZoom(tab_id, kZoomLevel)); EXPECT_EQ(kZoomLevel, - content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents))); + blink::PageZoomLevelToZoomFactor(GetZoomLevel(web_contents))); // Test chrome.tabs.getZoom(). zoom_factor = -1; @@ -1864,9 +1863,9 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest, GetDefaultZoom) { zoom::ZoomController::FromWebContents(web_contents); double default_zoom_factor = -1.0; EXPECT_TRUE(RunGetDefaultZoom(tab_id, &default_zoom_factor)); - EXPECT_TRUE(content::ZoomValuesEqual( + EXPECT_TRUE(blink::PageZoomValuesEqual( zoom_controller->GetDefaultZoomLevel(), - content::ZoomFactorToZoomLevel(default_zoom_factor))); + blink::PageZoomFactorToZoomLevel(default_zoom_factor))); // Change the default zoom level and verify GetDefaultZoom returns the // correct value. @@ -1880,9 +1879,9 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest, GetDefaultZoom) { zoom_prefs->SetDefaultZoomLevelPref(default_zoom_level + 0.5); default_zoom_factor = -1.0; EXPECT_TRUE(RunGetDefaultZoom(tab_id, &default_zoom_factor)); - EXPECT_TRUE(content::ZoomValuesEqual( + EXPECT_TRUE(blink::PageZoomValuesEqual( default_zoom_level + 0.5, - content::ZoomFactorToZoomLevel(default_zoom_factor))); + blink::PageZoomFactorToZoomLevel(default_zoom_factor))); } IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest, SetToDefaultZoom) { @@ -1906,9 +1905,9 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest, SetToDefaultZoom) { double observed_zoom_factor = -1.0; EXPECT_TRUE(RunSetZoom(tab_id, 0.0)); EXPECT_TRUE(RunGetZoom(tab_id, &observed_zoom_factor)); - EXPECT_TRUE(content::ZoomValuesEqual( + EXPECT_TRUE(blink::PageZoomValuesEqual( new_default_zoom_level, - content::ZoomFactorToZoomLevel(observed_zoom_factor))); + blink::PageZoomFactorToZoomLevel(observed_zoom_factor))); } IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest, ZoomSettings) { @@ -1936,48 +1935,48 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest, ZoomSettings) { int tab_id_B = ExtensionTabUtil::GetTabId(web_contents_B); ASSERT_FLOAT_EQ( - 1.f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1))); + 1.f, blink::PageZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1))); ASSERT_FLOAT_EQ( - 1.f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2))); + 1.f, blink::PageZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2))); ASSERT_FLOAT_EQ( - 1.f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_B))); + 1.f, blink::PageZoomLevelToZoomFactor(GetZoomLevel(web_contents_B))); // Test per-origin automatic zoom settings. EXPECT_TRUE(RunSetZoom(tab_id_B, 1.f)); EXPECT_TRUE(RunSetZoom(tab_id_A2, 1.1f)); EXPECT_FLOAT_EQ( - 1.1f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1))); + 1.1f, blink::PageZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1))); EXPECT_FLOAT_EQ( - 1.1f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2))); - EXPECT_FLOAT_EQ(1.f, - content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_B))); + 1.1f, blink::PageZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2))); + EXPECT_FLOAT_EQ( + 1.f, blink::PageZoomLevelToZoomFactor(GetZoomLevel(web_contents_B))); // Test per-tab automatic zoom settings. EXPECT_TRUE(RunSetZoomSettings(tab_id_A1, "automatic", "per-tab")); EXPECT_TRUE(RunSetZoom(tab_id_A1, 1.2f)); EXPECT_FLOAT_EQ( - 1.2f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1))); + 1.2f, blink::PageZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1))); EXPECT_FLOAT_EQ( - 1.1f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2))); + 1.1f, blink::PageZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2))); // Test 'manual' mode. EXPECT_TRUE(RunSetZoomSettings(tab_id_A1, "manual", nullptr)); EXPECT_TRUE(RunSetZoom(tab_id_A1, 1.3f)); EXPECT_FLOAT_EQ( - 1.3f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1))); + 1.3f, blink::PageZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1))); EXPECT_FLOAT_EQ( - 1.1f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2))); + 1.1f, blink::PageZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2))); // Test 'disabled' mode, which will reset A1's zoom to 1.f. EXPECT_TRUE(RunSetZoomSettings(tab_id_A1, "disabled", nullptr)); std::string error = RunSetZoomExpectError(tab_id_A1, 1.4f); EXPECT_TRUE(base::MatchPattern(error, keys::kCannotZoomDisabledTabError)); EXPECT_FLOAT_EQ( - 1.f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1))); + 1.f, blink::PageZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1))); // We should still be able to zoom A2 though. EXPECT_TRUE(RunSetZoom(tab_id_A2, 1.4f)); EXPECT_FLOAT_EQ( - 1.4f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2))); + 1.4f, blink::PageZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2))); } IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest, PerTabResetsOnNavigation) { @@ -2061,13 +2060,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest, CannotZoomInvalidTab) { } // Regression test for crbug.com/660498. -// TODO(crbug.com/882213) Disabled due to timeouts on Linux builders. -#if defined(OS_LINUX) -#define MAYBE_TemporaryAddressSpoof DISABLED_TemporaryAddressSpoof -#else -#define MAYBE_TemporaryAddressSpoof TemporaryAddressSpoof -#endif -IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_TemporaryAddressSpoof) { +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TemporaryAddressSpoof) { ASSERT_TRUE(StartEmbeddedTestServer()); content::WebContents* first_web_contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -2115,6 +2108,10 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_TemporaryAddressSpoof) { browser()->tab_strip_model()->GetActiveWebContents()); EXPECT_EQ(url, second_web_contents->GetVisibleURL()); + + // Wait for the TestNavigationManager-initiated navigation to complete to + // avoid a race during browser teardown (see crbug.com/882213). + navigation_manager.WaitForNavigationFinished(); } // Tests how chrome.windows.create behaves when setSelfAsOpener parameter is diff --git a/chromium/chrome/browser/extensions/api/tabs/tabs_util_chromeos.cc b/chromium/chrome/browser/extensions/api/tabs/tabs_util_chromeos.cc index 6a0c9a2833f..9a4b1776deb 100644 --- a/chromium/chrome/browser/extensions/api/tabs/tabs_util_chromeos.cc +++ b/chromium/chrome/browser/extensions/api/tabs/tabs_util_chromeos.cc @@ -4,13 +4,13 @@ #include "chrome/browser/extensions/api/tabs/tabs_util.h" +#include "ash/public/cpp/assistant/assistant_state.h" #include "ash/public/cpp/window_pin_type.h" #include "ash/public/cpp/window_properties.h" #include "base/metrics/histogram_macros.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" -#include "chrome/browser/chromeos/arc/arc_session_manager.h" #include "chrome/browser/chromeos/arc/arc_util.h" -#include "chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.h" +#include "chrome/browser/chromeos/arc/session/arc_session_manager.h" #include "chrome/browser/chromeos/assistant/assistant_util.h" #include "chrome/browser/ui/ash/chrome_screenshot_grabber.h" #include "chrome/browser/ui/browser.h" @@ -62,8 +62,7 @@ void SetLockedFullscreenState(Browser* browser, bool locked) { if (assistant::IsAssistantAllowedForProfile(profile) == ash::mojom::AssistantAllowedState::ALLOWED) { - arc::VoiceInteractionControllerClient::Get() - ->NotifyLockedFullScreenStateChanged(locked); + ash::AssistantState::Get()->NotifyLockedFullScreenStateChanged(locked); } } diff --git a/chromium/chrome/browser/extensions/api/tabs/windows_event_router.cc b/chromium/chrome/browser/extensions/api/tabs/windows_event_router.cc index c890c88293c..5f41fa24c34 100644 --- a/chromium/chrome/browser/extensions/api/tabs/windows_event_router.cc +++ b/chromium/chrome/browser/extensions/api/tabs/windows_event_router.cc @@ -17,7 +17,6 @@ #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/extensions/window_controller.h" -#include "chrome/browser/extensions/window_controller_list.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/api/windows.h" #include "chrome/common/extensions/extension_constants.h" @@ -148,9 +147,7 @@ bool WillDispatchWindowFocusedEvent( WindowsEventRouter::WindowsEventRouter(Profile* profile) : profile_(profile), focused_profile_(nullptr), - focused_window_id_(extension_misc::kUnknownWindowId), - observed_app_registry_(this), - observed_controller_list_(this) { + focused_window_id_(extension_misc::kUnknownWindowId) { DCHECK(!profile->IsOffTheRecord()); observed_app_registry_.Add(AppWindowRegistry::Get(profile_)); diff --git a/chromium/chrome/browser/extensions/api/tabs/windows_event_router.h b/chromium/chrome/browser/extensions/api/tabs/windows_event_router.h index 0f9d46ff565..ce4bcaec46b 100644 --- a/chromium/chrome/browser/extensions/api/tabs/windows_event_router.h +++ b/chromium/chrome/browser/extensions/api/tabs/windows_event_router.h @@ -12,6 +12,7 @@ #include "base/macros.h" #include "base/scoped_observer.h" #include "build/build_config.h" +#include "chrome/browser/extensions/window_controller_list.h" #include "chrome/browser/extensions/window_controller_list_observer.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -32,7 +33,6 @@ namespace extensions { class AppWindow; class AppWindowController; -class WindowControllerList; // The WindowsEventRouter sends chrome.windows.* events to listeners // inside extension process renderers. The router listens to *all* events, @@ -97,11 +97,11 @@ class WindowsEventRouter : public AppWindowRegistry::Observer, // Observed AppWindowRegistry. ScopedObserver<AppWindowRegistry, AppWindowRegistry::Observer> - observed_app_registry_; + observed_app_registry_{this}; // Observed WindowControllerList. ScopedObserver<WindowControllerList, WindowControllerListObserver> - observed_controller_list_; + observed_controller_list_{this}; DISALLOW_COPY_AND_ASSIGN(WindowsEventRouter); }; diff --git a/chromium/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc b/chromium/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc index 2a0832b667a..425a808d8ea 100644 --- a/chromium/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc +++ b/chromium/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc @@ -257,7 +257,7 @@ bool ChromeVirtualKeyboardDelegate::ShowLanguageSettings() { base::RecordAction(base::UserMetricsAction("OpenLanguageOptionsDialog")); chrome::ShowSettingsSubPageForProfile(ProfileManager::GetActiveUserProfile(), - chrome::kLanguageOptionsSubPage); + chrome::kLanguageSubPage); return true; } @@ -383,8 +383,15 @@ void ChromeVirtualKeyboardDelegate::OnHasInputDevices( "fstinputlogic", base::FeatureList::IsEnabled(chromeos::features::kImeInputLogicFst))); features->AppendString(GenerateFeatureFlag( - "fstnonenglish", base::FeatureList::IsEnabled( - chromeos::features::kImeInputLogicFstNonEnglish))); + "fstnonenglish", + base::FeatureList::IsEnabled(chromeos::features::kImeInputLogicFst))); + features->AppendString(GenerateFeatureFlag( + "floatingkeyboarddefault", + base::FeatureList::IsEnabled( + chromeos::features::kVirtualKeyboardFloatingDefault))); + features->AppendString(GenerateFeatureFlag( + "mozcinputlogic", + base::FeatureList::IsEnabled(chromeos::features::kImeInputLogicMozc))); results->Set("features", std::move(features)); diff --git a/chromium/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc b/chromium/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc index 98483bc6950..4c7a4ed1b8d 100644 --- a/chromium/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc +++ b/chromium/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc @@ -260,7 +260,7 @@ void WebNavigationTabObserver::DidFinishNavigation( HandleError(navigation_handle); } -void WebNavigationTabObserver::DocumentLoadedInFrame( +void WebNavigationTabObserver::DOMContentLoaded( content::RenderFrameHost* render_frame_host) { if (!navigation_state_.CanSendEvents(render_frame_host)) return; diff --git a/chromium/chrome/browser/extensions/api/web_navigation/web_navigation_api.h b/chromium/chrome/browser/extensions/api/web_navigation/web_navigation_api.h index d5169edb107..2bfcc079c5c 100644 --- a/chromium/chrome/browser/extensions/api/web_navigation/web_navigation_api.h +++ b/chromium/chrome/browser/extensions/api/web_navigation/web_navigation_api.h @@ -51,8 +51,7 @@ class WebNavigationTabObserver content::NavigationHandle* navigation_handle) override; void DidFinishNavigation( content::NavigationHandle* navigation_handle) override; - void DocumentLoadedInFrame( - content::RenderFrameHost* render_frame_host) override; + void DOMContentLoaded(content::RenderFrameHost* render_frame_host) override; void DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) override; void DidFailLoad(content::RenderFrameHost* render_frame_host, diff --git a/chromium/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc b/chromium/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc index 2e416ee7641..98f99625b2f 100644 --- a/chromium/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc +++ b/chromium/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc @@ -51,6 +51,7 @@ #include "extensions/common/features/feature.h" #include "google_apis/gaia/gaia_urls.h" #include "net/http/http_util.h" +#include "services/network/public/cpp/features.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest-message.h" #include "testing/gtest/include/gtest/gtest.h" @@ -87,7 +88,7 @@ using helpers::ResponseHeader; using helpers::ResponseHeaders; using helpers::StringToCharList; using testing::ElementsAre; -using Action = extensions::declarative_net_request::RulesetManager::Action; +using DNRRequestAction = extensions::declarative_net_request::RequestAction; namespace extensions { @@ -171,14 +172,16 @@ namespace { // Create the numerical representation of |values|, strings passed as // extraInfoSpec by the event handler. Returns true on success, otherwise false. -bool GenerateInfoSpec(const std::string& values, int* result) { +bool GenerateInfoSpec(content::BrowserContext* browser_context, + const std::string& values, + int* result) { // Create a base::ListValue of strings. base::ListValue list_value; for (const std::string& cur : base::SplitString(values, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) list_value.AppendString(cur); - return ExtraInfoSpec::InitFromValue(list_value, result); + return ExtraInfoSpec::InitFromValue(browser_context, list_value, result); } } // namespace @@ -230,10 +233,13 @@ TEST_F(ExtensionWebRequestTest, AddAndRemoveListeners) { namespace { -void TestInitFromValue(const std::string& values, bool expected_return_code, +void TestInitFromValue(content::BrowserContext* browser_context, + const std::string& values, + bool expected_return_code, int expected_extra_info_spec) { int actual_info_spec; - bool actual_return_code = GenerateInfoSpec(values, &actual_info_spec); + bool actual_return_code = + GenerateInfoSpec(browser_context, values, &actual_info_spec); EXPECT_EQ(expected_return_code, actual_return_code); if (expected_return_code) EXPECT_EQ(expected_extra_info_spec, actual_info_spec); @@ -242,43 +248,30 @@ void TestInitFromValue(const std::string& values, bool expected_return_code, } // namespace TEST_F(ExtensionWebRequestTest, InitFromValue) { - TestInitFromValue(std::string(), true, 0); + TestInitFromValue(&profile_, std::string(), true, 0); // Single valid values. - TestInitFromValue( - "requestHeaders", - true, - ExtraInfoSpec::REQUEST_HEADERS); - TestInitFromValue( - "responseHeaders", - true, - ExtraInfoSpec::RESPONSE_HEADERS); - TestInitFromValue( - "blocking", - true, - ExtraInfoSpec::BLOCKING); - TestInitFromValue( - "asyncBlocking", - true, - ExtraInfoSpec::ASYNC_BLOCKING); - TestInitFromValue( - "requestBody", - true, - ExtraInfoSpec::REQUEST_BODY); + TestInitFromValue(&profile_, "requestHeaders", true, + ExtraInfoSpec::REQUEST_HEADERS); + TestInitFromValue(&profile_, "responseHeaders", true, + ExtraInfoSpec::RESPONSE_HEADERS); + TestInitFromValue(&profile_, "blocking", true, ExtraInfoSpec::BLOCKING); + TestInitFromValue(&profile_, "asyncBlocking", true, + ExtraInfoSpec::ASYNC_BLOCKING); + TestInitFromValue(&profile_, "requestBody", true, + ExtraInfoSpec::REQUEST_BODY); // Multiple valid values are bitwise-or'ed. - TestInitFromValue( - "requestHeaders,blocking", - true, - ExtraInfoSpec::REQUEST_HEADERS | ExtraInfoSpec::BLOCKING); + TestInitFromValue(&profile_, "requestHeaders,blocking", true, + ExtraInfoSpec::REQUEST_HEADERS | ExtraInfoSpec::BLOCKING); // Any invalid values lead to a bad parse. - TestInitFromValue("invalidValue", false, 0); - TestInitFromValue("blocking,invalidValue", false, 0); - TestInitFromValue("invalidValue1,invalidValue2", false, 0); + TestInitFromValue(&profile_, "invalidValue", false, 0); + TestInitFromValue(&profile_, "blocking,invalidValue", false, 0); + TestInitFromValue(&profile_, "invalidValue1,invalidValue2", false, 0); // BLOCKING and ASYNC_BLOCKING are mutually exclusive. - TestInitFromValue("blocking,asyncBlocking", false, 0); + TestInitFromValue(&profile_, "blocking,asyncBlocking", false, 0); } TEST(ExtensionWebRequestHelpersTest, @@ -332,8 +325,8 @@ TEST(ExtensionWebRequestHelpersTest, TestCalculateOnBeforeSendHeadersDelta) { new_headers_added.SetHeader("key3", "value3"); new_headers_added.SetHeader("key2", "value2"); EventResponseDelta delta_added = CalculateOnBeforeSendHeadersDelta( - "extid", base::Time::Now(), cancel, &old_headers, &new_headers_added, - 0 /* extra_info_spec */); + nullptr /* browser_context */, "extid", base::Time::Now(), cancel, + &old_headers, &new_headers_added, 0 /* extra_info_spec */); EXPECT_TRUE(delta_added.cancel); ASSERT_TRUE(delta_added.modified_request_headers.GetHeader("key3", &value)); EXPECT_EQ("value3", value); @@ -342,8 +335,8 @@ TEST(ExtensionWebRequestHelpersTest, TestCalculateOnBeforeSendHeadersDelta) { net::HttpRequestHeaders new_headers_deleted; new_headers_deleted.SetHeader("key1", "value1"); EventResponseDelta delta_deleted = CalculateOnBeforeSendHeadersDelta( - "extid", base::Time::Now(), cancel, &old_headers, &new_headers_deleted, - 0 /* extra_info_spec */); + nullptr /* browser_context */, "extid", base::Time::Now(), cancel, + &old_headers, &new_headers_deleted, 0 /* extra_info_spec */); ASSERT_EQ(1u, delta_deleted.deleted_request_headers.size()); ASSERT_EQ("key2", delta_deleted.deleted_request_headers.front()); @@ -352,8 +345,8 @@ TEST(ExtensionWebRequestHelpersTest, TestCalculateOnBeforeSendHeadersDelta) { new_headers_modified.SetHeader("key1", "value1"); new_headers_modified.SetHeader("key2", "value3"); EventResponseDelta delta_modified = CalculateOnBeforeSendHeadersDelta( - "extid", base::Time::Now(), cancel, &old_headers, &new_headers_modified, - 0 /* extra_info_spec */); + nullptr /* browser_context */, "extid", base::Time::Now(), cancel, + &old_headers, &new_headers_modified, 0 /* extra_info_spec */); EXPECT_TRUE(delta_modified.deleted_request_headers.empty()); ASSERT_TRUE( delta_modified.modified_request_headers.GetHeader("key2", &value)); @@ -367,8 +360,8 @@ TEST(ExtensionWebRequestHelpersTest, TestCalculateOnBeforeSendHeadersDelta) { new_headers_modified2.SetHeader("key2", "value2"); new_headers_modified2.SetHeader("key2", "value3"); EventResponseDelta delta_modified2 = CalculateOnBeforeSendHeadersDelta( - "extid", base::Time::Now(), cancel, &old_headers, &new_headers_modified, - 0 /* extra_info_spec */); + nullptr /* browser_context */, "extid", base::Time::Now(), cancel, + &old_headers, &new_headers_modified, 0 /* extra_info_spec */); EXPECT_TRUE(delta_modified2.deleted_request_headers.empty()); ASSERT_TRUE( delta_modified2.modified_request_headers.GetHeader("key2", &value)); @@ -386,14 +379,14 @@ TEST(ExtensionWebRequestHelpersTest, net::HttpRequestHeaders new_headers = old_headers; new_headers.SetHeader(name, "value"); EventResponseDelta delta = CalculateOnBeforeSendHeadersDelta( - "extid", base::Time::Now(), false, &old_headers, &new_headers, - 0 /* extra_info_spec */); + nullptr /* browser_context */, "extid", base::Time::Now(), false, + &old_headers, &new_headers, 0 /* extra_info_spec */); EXPECT_FALSE(delta.modified_request_headers.HasHeader(name)); // Test with extra headers in spec. - delta = CalculateOnBeforeSendHeadersDelta("extid", base::Time::Now(), false, - &old_headers, &new_headers, - ExtraInfoSpec::EXTRA_HEADERS); + delta = CalculateOnBeforeSendHeadersDelta( + nullptr /* browser_context */, "extid", base::Time::Now(), false, + &old_headers, &new_headers, ExtraInfoSpec::EXTRA_HEADERS); std::string value; EXPECT_TRUE(delta.modified_request_headers.GetHeader(name, &value)); EXPECT_EQ("value", value); @@ -402,15 +395,15 @@ TEST(ExtensionWebRequestHelpersTest, new_headers = old_headers; // Add header to old headers, it will be treated as removed. old_headers.SetHeader(name, "value"); - delta = CalculateOnBeforeSendHeadersDelta("extid", base::Time::Now(), false, - &old_headers, &new_headers, - 0 /* extra_info_spec */); + delta = CalculateOnBeforeSendHeadersDelta( + nullptr /* browser_context */, "extid", base::Time::Now(), false, + &old_headers, &new_headers, 0 /* extra_info_spec */); EXPECT_TRUE(delta.deleted_request_headers.empty()); // Test with extra headers in spec. - delta = CalculateOnBeforeSendHeadersDelta("extid", base::Time::Now(), false, - &old_headers, &new_headers, - ExtraInfoSpec::EXTRA_HEADERS); + delta = CalculateOnBeforeSendHeadersDelta( + nullptr /* browser_context */, "extid", base::Time::Now(), false, + &old_headers, &new_headers, ExtraInfoSpec::EXTRA_HEADERS); EXPECT_THAT(delta.deleted_request_headers, ElementsAre(name)); } } @@ -771,7 +764,7 @@ TEST(ExtensionWebRequestHelpersTest, TestMergeOnBeforeSendHeadersResponses) { headers0.MergeFrom(base_headers); WebRequestInfoInitParams info_params; WebRequestInfo info(std::move(info_params)); - info.dnr_action.emplace(Action::Type::NONE); + info.dnr_actions = std::vector<DNRRequestAction>(); MergeOnBeforeSendHeadersResponses(info, deltas, &headers0, &ignored_actions, &ignore1, &ignore2, &request_headers_modified0); @@ -879,8 +872,12 @@ TEST(ExtensionWebRequestHelpersTest, TestMergeOnBeforeSendHeadersResponses) { bool request_headers_modified4 = false; net::HttpRequestHeaders headers4; headers4.MergeFrom(base_headers); - info.dnr_action.emplace(Action::Type::REMOVE_HEADERS); - info.dnr_action->request_headers_to_remove = {"key5"}; + + DNRRequestAction remove_headers_action( + DNRRequestAction::Type::REMOVE_HEADERS); + remove_headers_action.request_headers_to_remove = {"key5"}; + info.dnr_actions = std::vector<DNRRequestAction>(); + info.dnr_actions->push_back(std::move(remove_headers_action)); MergeOnBeforeSendHeadersResponses(info, deltas, &headers4, &ignored_actions, &ignore1, &ignore2, &request_headers_modified4); @@ -927,7 +924,7 @@ TEST(ExtensionWebRequestHelpersTest, WebRequestInfoInitParams info_params; WebRequestInfo info(std::move(info_params)); - info.dnr_action.emplace(Action::Type::NONE); + info.dnr_actions = std::vector<DNRRequestAction>(); helpers::IgnoredActions ignored_actions; std::set<std::string> removed_headers, set_headers; bool request_headers_modified = false; @@ -1270,7 +1267,7 @@ TEST(ExtensionWebRequestHelpersTest, TestMergeOnHeadersReceivedResponses) { WebRequestInfoInitParams info_params; info_params.url = GURL(kExampleUrl); WebRequestInfo info(std::move(info_params)); - info.dnr_action.emplace(Action::Type::NONE); + info.dnr_actions = std::vector<DNRRequestAction>(); MergeOnHeadersReceivedResponses(info, deltas, base_headers.get(), &new_headers0, &allowed_unsafe_redirect_url0, @@ -1350,8 +1347,12 @@ TEST(ExtensionWebRequestHelpersTest, TestMergeOnHeadersReceivedResponses) { // Ensure headers removed by Declarative Net Request API can't be added by web // request extensions and result in a conflict. - info.dnr_action.emplace(Action::Type::REMOVE_HEADERS); - info.dnr_action->response_headers_to_remove = {"key3"}; + DNRRequestAction remove_headers_action( + DNRRequestAction::Type::REMOVE_HEADERS); + remove_headers_action.response_headers_to_remove = {"key3"}; + info.dnr_actions = std::vector<DNRRequestAction>(); + info.dnr_actions->push_back(std::move(remove_headers_action)); + ignored_actions.clear(); bool response_headers_modified3 = false; scoped_refptr<net::HttpResponseHeaders> new_headers3; @@ -1406,7 +1407,7 @@ TEST(ExtensionWebRequestHelpersTest, WebRequestInfoInitParams info_params; info_params.url = GURL(kExampleUrl); WebRequestInfo info(std::move(info_params)); - info.dnr_action.emplace(Action::Type::NONE); + info.dnr_actions = std::vector<DNRRequestAction>(); MergeOnHeadersReceivedResponses(info, deltas, base_headers.get(), &new_headers1, &allowed_unsafe_redirect_url1, diff --git a/chromium/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chromium/chrome/browser/extensions/api/web_request/web_request_apitest.cc index 622cdec21a1..7cbbb84af36 100644 --- a/chromium/chrome/browser/extensions/api/web_request/web_request_apitest.cc +++ b/chromium/chrome/browser/extensions/api/web_request/web_request_apitest.cc @@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/command_line.h" +#include "base/json/json_reader.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/optional.h" @@ -28,6 +29,7 @@ #include "chrome/browser/extensions/extension_action_runner.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/extension_with_management_policy_apitest.h" #include "chrome/browser/extensions/scripting_permissions_modifier.h" @@ -100,6 +102,7 @@ #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request_filter.h" #include "net/url_request/url_request_interceptor.h" +#include "services/network/public/cpp/features.h" #include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/simple_url_loader.h" #include "services/network/test/test_url_loader_client.h" @@ -141,6 +144,55 @@ class CancelLoginDialog : public content::NotificationObserver { DISALLOW_COPY_AND_ASSIGN(CancelLoginDialog); }; +// Observer that listens for messages from chrome.test.sendMessage to allow them +// to be used to trigger browser initiated naviagations from the javascript for +// testing purposes. +class NavigateTabMessageHandler : public content::NotificationObserver { + public: + explicit NavigateTabMessageHandler(Profile* profile) : profile_(profile) { + registrar_.Add(this, extensions::NOTIFICATION_EXTENSION_TEST_MESSAGE, + content::NotificationService::AllSources()); + } + + ~NavigateTabMessageHandler() override {} + + void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override { + HandleNavigateTabMessage(type, source, details, profile_); + } + + private: + void HandleNavigateTabMessage(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details, + Profile* profile) { + DCHECK_EQ(NOTIFICATION_EXTENSION_TEST_MESSAGE, type); + const auto message = + content::Details<std::pair<std::string, bool*>>(details)->first; + base::Optional<base::Value> command = base::JSONReader::Read(message); + if (command && command->is_dict()) { // Check the message decoded from JSON + base::Value* data = command->FindDictKey("navigate"); + if (data && data->is_dict()) { + int tab_id = *data->FindIntKey("tabId"); + GURL url = GURL(*data->FindStringKey("url")); + ASSERT_TRUE(url.is_valid()); + + content::WebContents* contents = nullptr; + ExtensionTabUtil::GetTabById( + tab_id, profile, profile->HasOffTheRecordProfile(), &contents); + ASSERT_NE(contents, nullptr) + << "Could not find tab with id: " << tab_id; + content::NavigationController::LoadURLParams params(url); + contents->GetController().LoadURLWithParams(params); + } + } + } + + content::NotificationRegistrar registrar_; + Profile* profile_; +}; + // Sends an XHR request to the provided host, port, and path, and responds when // the request was sent. const char kPerformXhrJs[] = @@ -230,6 +282,7 @@ class ExtensionWebRequestApiTest : public ExtensionApiTest { void SetUpOnMainThread() override { ExtensionApiTest::SetUpOnMainThread(); host_resolver()->AddRule("*", "127.0.0.1"); + navigationHandler_ = std::make_unique<NavigateTabMessageHandler>(profile()); } void SetUpCommandLine(base::CommandLine* command_line) override { @@ -274,6 +327,7 @@ class ExtensionWebRequestApiTest : public ExtensionApiTest { private: std::vector<std::unique_ptr<TestExtensionDir>> test_dirs_; + std::unique_ptr<NavigateTabMessageHandler> navigationHandler_; }; class DevToolsFrontendInWebRequestApiTest : public ExtensionApiTest { @@ -287,6 +341,8 @@ class DevToolsFrontendInWebRequestApiTest : public ExtensionApiTest { url_loader_interceptor_ = std::make_unique<content::URLLoaderInterceptor>( base::BindRepeating(&DevToolsFrontendInWebRequestApiTest::OnIntercept, base::Unretained(this), port)); + + navigationHandler_ = std::make_unique<NavigateTabMessageHandler>(profile()); } void TearDownOnMainThread() override { @@ -352,6 +408,7 @@ class DevToolsFrontendInWebRequestApiTest : public ExtensionApiTest { base::FilePath test_root_dir_; std::unique_ptr<content::URLLoaderInterceptor> url_loader_interceptor_; + std::unique_ptr<NavigateTabMessageHandler> navigationHandler_; }; IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, WebRequestApi) { @@ -469,23 +526,30 @@ class ExtensionWebRequestApiAuthRequiredTest } }; +// Note: this is flaky on multiple platforms (crbug.com/1003598). IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiAuthRequiredTest, - WebRequestAuthRequired) { + DISABLED_WebRequestAuthRequired) { CancelLoginDialog login_dialog_helper; ASSERT_TRUE(StartEmbeddedTestServer()); + + // Pass "debug" as a custom arg to debug test flakiness. ASSERT_TRUE(RunExtensionSubtestWithArgAndFlags( - "webrequest", "test_auth_required.html", nullptr, GetFlags())) + "webrequest", "test_auth_required.html", "debug", GetFlags())) << message_; } +// Note: this is flaky on multiple platforms (crbug.com/1003598). Temporarily +// enabled to find flakiness cause. IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiAuthRequiredTest, - WebRequestAuthRequiredAsync) { + DISABLED_WebRequestAuthRequiredAsync) { CancelLoginDialog login_dialog_helper; ASSERT_TRUE(StartEmbeddedTestServer()); + + // Pass "debug" as a custom arg to debug test flakiness. ASSERT_TRUE(RunExtensionSubtestWithArgAndFlags( - "webrequest", "test_auth_required_async.html", nullptr, GetFlags())) + "webrequest", "test_auth_required_async.html", "debug", GetFlags())) << message_; } @@ -535,7 +599,15 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, << message_; } -IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, WebRequestExtraHeaders) { +// Flaky on ChromeOS: https://crbug.com/1003661 and Linux: +// https://crbug.com/1864717 +#if defined(OS_CHROMEOS) || defined(OS_LINUX) +#define MAYBE_WebRequestExtraHeaders DISABLED_WebRequestExtraHeaders +#else +#define MAYBE_WebRequestExtraHeaders WebRequestExtraHeaders +#endif +IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, + MAYBE_WebRequestExtraHeaders) { CancelLoginDialog login_dialog_helper; ASSERT_TRUE(StartEmbeddedTestServer()); @@ -546,7 +618,12 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, WebRequestExtraHeaders) { IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, WebRequestCORSWithExtraHeaders) { ASSERT_TRUE(StartEmbeddedTestServer()); - ASSERT_TRUE(RunExtensionSubtest("webrequest", "test_cors.html")) << message_; + std::string test = "test_cors.html"; + if (network::features::ShouldEnableOutOfBlinkCorsForTesting()) + test += "?cors_mode=network_service"; + else + test += "?cors_mode=blink"; + ASSERT_TRUE(RunExtensionSubtest("webrequest", test)) << message_; } IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, WebRequestRedirects) { @@ -869,7 +946,12 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, ExtensionRequests) { // The extension frame does run in the extension's process. Any requests made // by it should not be visible to other extensions, since they won't have // access to the request initiator. - EXPECT_EQ("Did not intercept any requests.", listener_result.message()); + // + // OTOH, the content script executes fetches/XHRs as-if they were initiated by + // the webpage that the content script got injected into. Here, the webpage + // has origin of http://127.0.0.1:<some port>, and so the webRequest API + // extension should have access to the request. + EXPECT_EQ("Intercepted requests: ?contentscript", listener_result.message()); } IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, HostedAppRequest) { diff --git a/chromium/chrome/browser/extensions/api/webrtc_logging_private/OWNERS b/chromium/chrome/browser/extensions/api/webrtc_logging_private/OWNERS index 67620a285c7..c954e4277f5 100644 --- a/chromium/chrome/browser/extensions/api/webrtc_logging_private/OWNERS +++ b/chromium/chrome/browser/extensions/api/webrtc_logging_private/OWNERS @@ -1 +1,3 @@ +eladalon@chromium.org grunell@chromium.org +guidou@chromium.org diff --git a/chromium/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc b/chromium/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc index dcff38d5276..8cc6edf6286 100644 --- a/chromium/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc +++ b/chromium/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc @@ -24,6 +24,7 @@ #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/install_tracker.h" +#include "chrome/browser/extensions/scoped_active_install.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" diff --git a/chromium/chrome/browser/extensions/api/webstore_private/webstore_private_api.h b/chromium/chrome/browser/extensions/api/webstore_private/webstore_private_api.h index 72f65444b0c..7bb1172e1cc 100644 --- a/chromium/chrome/browser/extensions/api/webstore_private/webstore_private_api.h +++ b/chromium/chrome/browser/extensions/api/webstore_private/webstore_private_api.h @@ -26,6 +26,7 @@ class GpuFeatureChecker; namespace extensions { class Extension; +class ScopedActiveInstall; class WebstorePrivateApi { public: |