diff --git a/DEPS b/DEPS index 601db6c..247bffe 100644 --- a/DEPS +++ b/DEPS
@@ -44,7 +44,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '07efdd707852ef8b9aca212417e824a13652f8cb', + 'v8_revision': '64c745349ec8e447722ec903aad31e7380cbcfc9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -363,7 +363,7 @@ Var('chromium_git') + '/external/github.com/swisspol/GCDWebServer.git' + '@' + '43555c66627f6ed44817855a0f6d465f559d30e0', 'src/ios/third_party/material_components_ios/src': - Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'd08f9c0c1926fce2964cffbc163385896c86798a', + Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'cb191e7c014cc871b5351a3911a1d0bc71b71699', 'src/ios/third_party/material_font_disk_loader_ios/src': Var('chromium_git') + '/external/github.com/material-foundation/material-font-disk-loader-ios.git' + '@' + '8e30188777b016182658fbaa0a4a020a48183224',
diff --git a/build/linux/sysroot_scripts/install-sysroot.py b/build/linux/sysroot_scripts/install-sysroot.py index 90b7068..181ac936 100755 --- a/build/linux/sysroot_scripts/install-sysroot.py +++ b/build/linux/sysroot_scripts/install-sysroot.py
@@ -64,17 +64,17 @@ detected_host_arch = detect_host_arch.HostArch() if detected_host_arch == 'x64': return 'amd64' - elif detected_host_arch == 'ia32': + if detected_host_arch == 'ia32': return 'i386' - elif detected_host_arch == 'arm': + if detected_host_arch == 'arm': return 'arm' - elif detected_host_arch == 'arm64': + if detected_host_arch == 'arm64': return 'arm64' - elif detected_host_arch == 'mips': + if detected_host_arch == 'mips': return 'mips' - elif detected_host_arch == 'ppc': + if detected_host_arch == 'ppc': return 'ppc' - elif detected_host_arch == 's390': + if detected_host_arch == 's390': return 's390' raise Error('Unrecognized host arch: %s' % detected_host_arch) @@ -93,13 +93,13 @@ target_arch = gyp_defines.get('target_arch') if target_arch == 'x64': return 'amd64' - elif target_arch == 'ia32': + if target_arch == 'ia32': return 'i386' - elif target_arch == 'arm': + if target_arch == 'arm': return 'arm' - elif target_arch == 'arm64': + if target_arch == 'arm64': return 'arm64' - elif target_arch == 'mipsel': + if target_arch == 'mipsel': return 'mips' return None
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 7f8bf12a..b9d9861 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -8784,8 +8784,8 @@ <message name="IDS_SYNC_CONFIRMATION_PERSONALIZE_SERVICES_BODY_CHILD_ACCOUNT" desc="Body of the personalize services section of the sync confirmation dialog in the tab modal signin flow for child accounts" formatter_data="android_java"> Google may use your browsing history to personalize Search and other Google services </message> - <message name="IDS_SYNC_CONFIRMATION_SYNC_SETTINGS_LABEL" desc="Label of the checkbox that allows users to configure their sync settings on the settings page before signing in to Chrome."> - Manage Chrome Sync and personalization in Settings + <message name="IDS_SYNC_CONFIRMATION_SYNC_SETTINGS_LINK_BODY" desc="Label of the section containing the link to go to the sync setting page."> + Manage Chrome Sync and personalization in <ph name="BEGIN_LINK"><a id="settingsLink" href="chrome://settings"></ph>Settings<ph name="END_LINK"></a><ex></a></ex></ph> </message> <message name="IDS_SYNC_CONFIRMATION_CONFIRM_BUTTON_LABEL" desc="Label of the confirmation button in the sync confirmation dialog of the tab modal signin flow"> Ok, got it
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 323cf399..b7ba2ec2 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1533,6 +1533,11 @@ flag_descriptions::kPasswordGenerationDescription, kOsAll, ENABLE_DISABLE_VALUE_TYPE(autofill::switches::kEnablePasswordGeneration, autofill::switches::kDisablePasswordGeneration)}, + {"enable-username-correction", + flag_descriptions::kEnableUsernameCorrectionName, + flag_descriptions::kEnableUsernameCorrectionDescription, + kOsWin | kOsLinux | kOsCrOS, + FEATURE_VALUE_TYPE(password_manager::features::kEnableUsernameCorrection)}, {"enable-password-force-saving", flag_descriptions::kPasswordForceSavingName, flag_descriptions::kPasswordForceSavingDescription, kOsAll, @@ -3191,6 +3196,12 @@ kOsDesktop, FEATURE_VALUE_TYPE(features::kCaptureThumbnailOnNavigatingAway)}, +#if defined(OS_CHROMEOS) + {"use-cros-midi-service", flag_descriptions::kUseCrosMidiServiceName, + flag_descriptions::kUseCrosMidiServiceNameDescription, kOsCrOS, + FEATURE_VALUE_TYPE(midi::features::kMidiManagerCros)}, +#endif // defined(OS_CHROMEOS) + // NOTE: Adding new command-line switches requires adding corresponding // entries to enum "LoginCustomFlags" in histograms/enums.xml. See note in // enums.xml and don't forget to run AboutFlagsHistogramTest unit test.
diff --git a/chrome/browser/browsing_data/bookmark_counter_unittest.cc b/chrome/browser/browsing_data/bookmark_counter_unittest.cc index 8aa8b17..a3d7d849 100644 --- a/chrome/browser/browsing_data/bookmark_counter_unittest.cc +++ b/chrome/browser/browsing_data/bookmark_counter_unittest.cc
@@ -42,7 +42,6 @@ void Callback( std::unique_ptr<browsing_data::BrowsingDataCounter::Result> result) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK(result->Finished()); finished_ = result->Finished(); result_ = static_cast<browsing_data::BrowsingDataCounter::FinishedResult*>( @@ -52,7 +51,6 @@ } void WaitForResult() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); run_loop_->Run(); run_loop_.reset(new base::RunLoop()); }
diff --git a/chrome/browser/browsing_data/browsing_data_channel_id_helper_unittest.cc b/chrome/browser/browsing_data/browsing_data_channel_id_helper_unittest.cc index 87dcd90..69a3b1d 100644 --- a/chrome/browser/browsing_data/browsing_data_channel_id_helper_unittest.cc +++ b/chrome/browser/browsing_data/browsing_data_channel_id_helper_unittest.cc
@@ -53,7 +53,6 @@ void FetchCallback( const net::ChannelIDStore::ChannelIDList& channel_ids) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); channel_id_list_ = channel_ids; }
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc index 4f9e43d..c2aa350 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -910,8 +910,6 @@ if (create_service) service_ = base::MakeUnique<MockReportingService>(); - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - net::URLRequestContext* request_context = profile_->GetRequestContext()->GetURLRequestContext(); old_service_ = request_context->reporting_service(); @@ -919,8 +917,6 @@ } ~ClearReportingCacheTester() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - net::URLRequestContext* request_context = profile_->GetRequestContext()->GetURLRequestContext(); DCHECK_EQ(service_.get(), request_context->reporting_service()); @@ -930,7 +926,6 @@ void GetMockInfo(int* remove_calls_out, int* last_data_type_mask_out, base::Callback<bool(const GURL&)>* last_origin_filter_out) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK_NE(nullptr, service_.get()); *remove_calls_out = service_->remove_calls();
diff --git a/chrome/browser/browsing_data/site_data_counting_helper_unittest.cc b/chrome/browser/browsing_data/site_data_counting_helper_unittest.cc index 2c322369..cb86e12 100644 --- a/chrome/browser/browsing_data/site_data_counting_helper_unittest.cc +++ b/chrome/browser/browsing_data/site_data_counting_helper_unittest.cc
@@ -31,6 +31,7 @@ void SetUp() override { profile_.reset(new TestingProfile()); + run_loop_.reset(new base::RunLoop()); tasks_ = 0; cookie_callback_ = base::Bind(&SiteDataCountingHelperTest::CookieCallback, base::Unretained(this)); @@ -44,7 +45,6 @@ void CookieCallback(int count) { // Negative values represent an unexpected error. DCHECK(count >= 0); - DCHECK_CURRENTLY_ON(BrowserThread::UI); last_count_ = count; if (run_loop_) @@ -61,16 +61,11 @@ base::Unretained(this))); } - void DoneCallback() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (run_loop_) - run_loop_->Quit(); - } + void DoneCallback() { run_loop_->Quit(); } void WaitForTasksOnIOThread() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - run_loop_.reset(new base::RunLoop()); run_loop_->Run(); + run_loop_.reset(new base::RunLoop()); } void CreateCookies(base::Time creation_time, @@ -107,8 +102,6 @@ const scoped_refptr<net::URLRequestContextGetter>& rq_context, base::Time creation_time, std::vector<std::string> urls) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - net::CookieStore* cookie_store = rq_context->GetURLRequestContext()->cookie_store(); @@ -128,7 +121,6 @@ } void CountEntries(base::Time begin_time) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); last_count_ = -1; auto* helper = new SiteDataCountingHelper(profile(), begin_time, cookie_callback_);
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 1ec4119..b757f5f 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -362,6 +362,8 @@ "arc/intent_helper/arc_navigation_throttle.h", "arc/intent_helper/arc_settings_service.cc", "arc/intent_helper/arc_settings_service.h", + "arc/kiosk/arc_kiosk_bridge.cc", + "arc/kiosk/arc_kiosk_bridge.h", "arc/notification/arc_boot_error_notification.cc", "arc/notification/arc_boot_error_notification.h", "arc/notification/arc_provision_notification_service.cc", @@ -1677,6 +1679,7 @@ "arc/fileapi/arc_file_system_operation_runner_unittest.cc", "arc/intent_helper/arc_external_protocol_dialog_unittest.cc", "arc/intent_helper/arc_navigation_throttle_unittest.cc", + "arc/kiosk/arc_kiosk_bridge_unittest.cc", "arc/notification/arc_provision_notification_service_unittest.cc", "arc/optin/arc_active_directory_auth_negotiator_unittest.cc", "arc/optin/arc_terms_of_service_default_negotiator_unittest.cc", @@ -1812,6 +1815,7 @@ "ownership/fake_owner_settings_service.cc", "ownership/fake_owner_settings_service.h", "ownership/owner_settings_service_chromeos_unittest.cc", + "policy/active_directory_policy_manager_unittest.cc", "policy/affiliated_cloud_policy_invalidator_unittest.cc", "policy/affiliated_invalidation_service_provider_impl_unittest.cc", "policy/android_management_client_unittest.cc",
diff --git a/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_service.h b/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_service.h index a737022..a210341 100644 --- a/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_service.h +++ b/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_service.h
@@ -9,9 +9,9 @@ #include "base/timer/timer.h" #include "chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_launcher.h" #include "chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager.h" +#include "chrome/browser/chromeos/arc/kiosk/arc_kiosk_bridge.h" #include "chrome/browser/ui/app_list/arc/arc_app_icon.h" #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" -#include "components/arc/kiosk/arc_kiosk_bridge.h" #include "components/keyed_service/core/keyed_service.h" #include "components/prefs/pref_change_registrar.h"
diff --git a/chrome/browser/chromeos/arc/arc_service_launcher.cc b/chrome/browser/chromeos/arc/arc_service_launcher.cc index 940d8a4..f2444f7a 100644 --- a/chrome/browser/chromeos/arc/arc_service_launcher.cc +++ b/chrome/browser/chromeos/arc/arc_service_launcher.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/logging.h" #include "base/memory/ptr_util.h" -#include "chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_service.h" #include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h" #include "chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler.h" #include "chrome/browser/chromeos/arc/arc_session_manager.h" @@ -21,6 +20,7 @@ #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_mounter.h" #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.h" #include "chrome/browser/chromeos/arc/intent_helper/arc_settings_service.h" +#include "chrome/browser/chromeos/arc/kiosk/arc_kiosk_bridge.h" #include "chrome/browser/chromeos/arc/notification/arc_boot_error_notification.h" #include "chrome/browser/chromeos/arc/notification/arc_provision_notification_service.h" #include "chrome/browser/chromeos/arc/policy/arc_policy_bridge.h" @@ -45,7 +45,6 @@ #include "components/arc/crash_collector/arc_crash_collector_bridge.h" #include "components/arc/ime/arc_ime_service.h" #include "components/arc/intent_helper/arc_intent_helper_bridge.h" -#include "components/arc/kiosk/arc_kiosk_bridge.h" #include "components/arc/metrics/arc_metrics_service.h" #include "components/arc/net/arc_net_host_impl.h" #include "components/arc/obb_mounter/arc_obb_mounter_bridge.h" @@ -53,7 +52,6 @@ #include "components/arc/storage_manager/arc_storage_manager.h" #include "components/arc/volume_mounter/arc_volume_mounter_bridge.h" #include "components/prefs/pref_member.h" -#include "components/user_manager/user_manager.h" #include "ui/arc/notification/arc_notification_manager.h" namespace arc { @@ -147,6 +145,7 @@ ArcFileSystemOperationRunner::GetForBrowserContext(profile); ArcImeService::GetForBrowserContext(profile); ArcIntentHelperBridge::GetForBrowserContext(profile); + ArcKioskBridge::GetForBrowserContext(profile); ArcMetricsService::GetForBrowserContext(profile); ArcNetHostImpl::GetForBrowserContext(profile); ArcNotificationManager::GetForBrowserContext(profile); @@ -166,15 +165,6 @@ ArcWallpaperService::GetForBrowserContext(profile); GpuArcVideoServiceHost::GetForBrowserContext(profile); - // Kiosk apps should be run only for kiosk sessions. - if (user_manager::UserManager::Get()->IsLoggedInAsArcKioskApp()) { - // ArcKioskAppService is BrowserContextKeyedService so that it's destroyed - // on destroying the Profile, that is after ArcServiceLauncher::Shutdown(). - arc_service_manager_->AddService(base::MakeUnique<ArcKioskBridge>( - arc_service_manager_->arc_bridge_service(), - chromeos::ArcKioskAppService::Get(profile))); - } - arc_session_manager_->Initialize(); arc_play_store_enabled_preference_handler_ = base::MakeUnique<ArcPlayStoreEnabledPreferenceHandler>(
diff --git a/chrome/browser/chromeos/arc/kiosk/arc_kiosk_bridge.cc b/chrome/browser/chromeos/arc/kiosk/arc_kiosk_bridge.cc new file mode 100644 index 0000000..64fa0bc --- /dev/null +++ b/chrome/browser/chromeos/arc/kiosk/arc_kiosk_bridge.cc
@@ -0,0 +1,112 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/kiosk/arc_kiosk_bridge.h" + +#include <utility> + +#include "base/memory/singleton.h" +#include "chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_service.h" +#include "chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_service_factory.h" +#include "components/arc/arc_bridge_service.h" +#include "components/arc/arc_browser_context_keyed_service_factory_base.h" +#include "components/user_manager/user_manager.h" + +namespace arc { +namespace { + +// Singleton factory for ArcKioskBridge. +class ArcKioskBridgeFactory + : public internal::ArcBrowserContextKeyedServiceFactoryBase< + ArcKioskBridge, + ArcKioskBridgeFactory> { + public: + // Factory name used by ArcBrowserContextKeyedServiceFactoryBase. + static constexpr const char* kName = "ArcKioskBridgeFactory"; + + static ArcKioskBridgeFactory* GetInstance() { + return base::Singleton<ArcKioskBridgeFactory>::get(); + } + + private: + friend base::DefaultSingletonTraits<ArcKioskBridgeFactory>; + + ArcKioskBridgeFactory() { + DependsOn(chromeos::ArcKioskAppServiceFactory::GetInstance()); + } + ~ArcKioskBridgeFactory() override = default; + + // BrowserContextKeyedServiceFactory override: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override { + // Kiosk apps should be run only for kiosk sessions. + if (!user_manager::UserManager::Get()->IsLoggedInAsArcKioskApp()) + return nullptr; + return ArcBrowserContextKeyedServiceFactoryBase::BuildServiceInstanceFor( + context); + } +}; + +} // namespace + +// static +ArcKioskBridge* ArcKioskBridge::GetForBrowserContext( + content::BrowserContext* context) { + return ArcKioskBridgeFactory::GetForBrowserContext(context); +} + +// static +std::unique_ptr<ArcKioskBridge> ArcKioskBridge::CreateForTesting( + ArcBridgeService* arc_bridge_service, + Delegate* delegate) { + // MakeUnique cannot be used because the ctor is private. + return base::WrapUnique(new ArcKioskBridge(arc_bridge_service, delegate)); +} + +ArcKioskBridge::ArcKioskBridge(content::BrowserContext* context, + ArcBridgeService* bridge_service) + : ArcKioskBridge(bridge_service, + chromeos::ArcKioskAppService::Get(context)) {} + +ArcKioskBridge::ArcKioskBridge(ArcBridgeService* bridge_service, + Delegate* delegate) + : arc_bridge_service_(bridge_service), binding_(this), delegate_(delegate) { + DCHECK(delegate_); + arc_bridge_service_->kiosk()->AddObserver(this); +} + +ArcKioskBridge::~ArcKioskBridge() { + // TODO(hidehiko): Currently, the lifetime of ArcBridgeService and + // BrowserContextKeyedService is not nested. + // If ArcServiceManager::Get() returns nullptr, it is already destructed, + // so do not touch it. + if (ArcServiceManager::Get()) + arc_bridge_service_->kiosk()->RemoveObserver(this); +} + +void ArcKioskBridge::OnInstanceReady() { + mojom::KioskInstance* kiosk_instance = + ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service_->kiosk(), Init); + DCHECK(kiosk_instance); + mojom::KioskHostPtr host_proxy; + binding_.Bind(mojo::MakeRequest(&host_proxy)); + kiosk_instance->Init(std::move(host_proxy)); +} + +void ArcKioskBridge::OnMaintenanceSessionCreated(int32_t session_id) { + session_id_ = session_id; + delegate_->OnMaintenanceSessionCreated(); + // TODO(poromov@) Show appropriate splash screen. +} + +void ArcKioskBridge::OnMaintenanceSessionFinished(int32_t session_id, + bool success) { + // Filter only callbacks for the started kiosk session. + if (session_id != session_id_) + return; + session_id_ = -1; + delegate_->OnMaintenanceSessionFinished(); +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/kiosk/arc_kiosk_bridge.h b/chrome/browser/chromeos/arc/kiosk/arc_kiosk_bridge.h new file mode 100644 index 0000000..8650edbc --- /dev/null +++ b/chrome/browser/chromeos/arc/kiosk/arc_kiosk_bridge.h
@@ -0,0 +1,74 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_ARC_KIOSK_ARC_KIOSK_BRIDGE_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_KIOSK_ARC_KIOSK_BRIDGE_H_ + +#include <memory> + +#include "base/macros.h" +#include "components/arc/common/kiosk.mojom.h" +#include "components/arc/instance_holder.h" +#include "components/keyed_service/core/keyed_service.h" +#include "mojo/public/cpp/bindings/binding.h" + +namespace content { +class BrowserContext; +} // namespace content + +namespace arc { + +class ArcBridgeService; + +// TODO(hidehiko): Consider to migrate this class into ArcKioskAppService. +class ArcKioskBridge : public KeyedService, + public InstanceHolder<mojom::KioskInstance>::Observer, + public mojom::KioskHost { + public: + // Received IPCs are passed to this delegate. + class Delegate { + public: + virtual ~Delegate() = default; + virtual void OnMaintenanceSessionCreated() = 0; + virtual void OnMaintenanceSessionFinished() = 0; + }; + + // Returns singleton instance for the given BrowserContext, + // or nullptr if the browser |context| is not allowed to use ARC. + static ArcKioskBridge* GetForBrowserContext(content::BrowserContext* context); + + // Returns a created instance for testing. + static std::unique_ptr<ArcKioskBridge> CreateForTesting( + ArcBridgeService* bridge_service, + Delegate* delegate); + + ArcKioskBridge(content::BrowserContext* context, + ArcBridgeService* bridge_service); + ~ArcKioskBridge() override; + + // InstanceHolder<mojom::KioskInstance>::Observer overrides. + void OnInstanceReady() override; + + // mojom::KioskHost overrides. + void OnMaintenanceSessionCreated(int32_t session_id) override; + void OnMaintenanceSessionFinished(int32_t session_id, bool success) override; + + private: + // |delegate| should be alive while the ArcKioskBridge instance is alive. + ArcKioskBridge(ArcBridgeService* bridge_service, Delegate* delegate); + + ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager. + + mojo::Binding<mojom::KioskHost> binding_; + Delegate* const delegate_; + + // Tracks current maintenance session id. + int32_t session_id_ = -1; + + DISALLOW_COPY_AND_ASSIGN(ArcKioskBridge); +}; + +} // namespace arc + +#endif // CHROME_BROWSER_CHROMEOS_ARC_KIOSK_ARC_KIOSK_BRIDGE_H_
diff --git a/components/arc/kiosk/arc_kiosk_bridge_unittest.cc b/chrome/browser/chromeos/arc/kiosk/arc_kiosk_bridge_unittest.cc similarity index 93% rename from components/arc/kiosk/arc_kiosk_bridge_unittest.cc rename to chrome/browser/chromeos/arc/kiosk/arc_kiosk_bridge_unittest.cc index b2243f7c..9b3b1f4 100644 --- a/components/arc/kiosk/arc_kiosk_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/kiosk/arc_kiosk_bridge_unittest.cc
@@ -6,8 +6,8 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "chrome/browser/chromeos/arc/kiosk/arc_kiosk_bridge.h" #include "components/arc/arc_bridge_service.h" -#include "components/arc/kiosk/arc_kiosk_bridge.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -30,7 +30,7 @@ ArcKioskBridgeTest() : bridge_service_(base::MakeUnique<ArcBridgeService>()), delegate_(base::MakeUnique<MockArcKioskBridgeDelegate>()), - kiosk_bridge_(base::MakeUnique<ArcKioskBridge>(bridge_service_.get(), + kiosk_bridge_(ArcKioskBridge::CreateForTesting(bridge_service_.get(), delegate_.get())) {} protected:
diff --git a/chrome/browser/chromeos/policy/active_directory_policy_manager.cc b/chrome/browser/chromeos/policy/active_directory_policy_manager.cc index 195140d..fc1fcbf 100644 --- a/chrome/browser/chromeos/policy/active_directory_policy_manager.cc +++ b/chrome/browser/chromeos/policy/active_directory_policy_manager.cc
@@ -31,17 +31,23 @@ std::unique_ptr<ActiveDirectoryPolicyManager> ActiveDirectoryPolicyManager::CreateForDevicePolicy( std::unique_ptr<CloudPolicyStore> store) { + // Can't use MakeUnique<> because the constructor is private. return base::WrapUnique( - new ActiveDirectoryPolicyManager(EmptyAccountId(), std::move(store))); + new ActiveDirectoryPolicyManager(EmptyAccountId(), base::TimeDelta(), + base::OnceClosure(), std::move(store))); } // static std::unique_ptr<ActiveDirectoryPolicyManager> ActiveDirectoryPolicyManager::CreateForUserPolicy( const AccountId& account_id, + base::TimeDelta initial_policy_fetch_timeout, + base::OnceClosure exit_session, std::unique_ptr<CloudPolicyStore> store) { - return base::WrapUnique( - new ActiveDirectoryPolicyManager(account_id, std::move(store))); + // Can't use MakeUnique<> because the constructor is private. + return base::WrapUnique(new ActiveDirectoryPolicyManager( + account_id, initial_policy_fetch_timeout, std::move(exit_session), + std::move(store))); } void ActiveDirectoryPolicyManager::Init(SchemaRegistry* registry) { @@ -56,7 +62,7 @@ PublishPolicy(); scheduler_ = base::MakeUnique<PolicyScheduler>( - base::BindRepeating(&ActiveDirectoryPolicyManager::DoFetch, + base::BindRepeating(&ActiveDirectoryPolicyManager::DoPolicyFetch, weak_ptr_factory_.GetWeakPtr()), base::BindRepeating(&ActiveDirectoryPolicyManager::OnPolicyFetched, weak_ptr_factory_.GetWeakPtr()), @@ -70,6 +76,9 @@ bool ActiveDirectoryPolicyManager::IsInitializationComplete( PolicyDomain domain) const { + if (waiting_for_initial_policy_fetch_) { + return false; + } if (domain == POLICY_DOMAIN_CHROME) { return store_->is_initialized(); } @@ -84,6 +93,12 @@ CloudPolicyStore* cloud_policy_store) { DCHECK_EQ(store_.get(), cloud_policy_store); PublishPolicy(); + if (fetch_ever_completed_) { + // Policy is guaranteed to be up to date with the previous fetch result + // because OnPolicyFetched() cancels any potentially running Load() + // operations. + CancelWaitForInitialPolicy(fetch_ever_succeeded_ /* success */); + } } void ActiveDirectoryPolicyManager::OnStoreError( @@ -93,12 +108,39 @@ // complete on the ConfigurationPolicyProvider interface. Technically, this is // only required on the first load, but doesn't hurt in any case. PublishPolicy(); + if (fetch_ever_completed_) { + CancelWaitForInitialPolicy(false /* success */); + } +} + +void ActiveDirectoryPolicyManager::ForceTimeoutForTest() { + DCHECK(initial_policy_timeout_.IsRunning()); + // Stop the timer to mimic what happens when a real timer fires, then invoke + // the timer callback directly. + initial_policy_timeout_.Stop(); + OnBlockingFetchTimeout(); } ActiveDirectoryPolicyManager::ActiveDirectoryPolicyManager( const AccountId& account_id, + base::TimeDelta initial_policy_fetch_timeout, + base::OnceClosure exit_session, std::unique_ptr<CloudPolicyStore> store) - : account_id_(account_id), store_(std::move(store)) {} + : account_id_(account_id), + waiting_for_initial_policy_fetch_( + !initial_policy_fetch_timeout.is_zero()), + initial_policy_fetch_may_fail_(!initial_policy_fetch_timeout.is_max()), + exit_session_(std::move(exit_session)), + store_(std::move(store)) { + // Delaying initialization complete is intended for user policy only. + DCHECK(account_id != EmptyAccountId() || !waiting_for_initial_policy_fetch_); + if (waiting_for_initial_policy_fetch_ && initial_policy_fetch_may_fail_) { + initial_policy_timeout_.Start( + FROM_HERE, initial_policy_fetch_timeout, + base::Bind(&ActiveDirectoryPolicyManager::OnBlockingFetchTimeout, + weak_ptr_factory_.GetWeakPtr())); + } +} void ActiveDirectoryPolicyManager::PublishPolicy() { if (!store_->is_initialized()) { @@ -117,7 +159,7 @@ UpdatePolicy(std::move(bundle)); } -void ActiveDirectoryPolicyManager::DoFetch( +void ActiveDirectoryPolicyManager::DoPolicyFetch( base::OnceCallback<void(bool success)> callback) { chromeos::DBusThreadManager* thread_manager = chromeos::DBusThreadManager::Get(); @@ -133,12 +175,65 @@ } void ActiveDirectoryPolicyManager::OnPolicyFetched(bool success) { - if (!success) { + fetch_ever_completed_ = true; + if (success) { + fetch_ever_succeeded_ = true; + } else { LOG(ERROR) << "Active Directory policy fetch failed."; + if (store_->is_initialized()) { + CancelWaitForInitialPolicy(false /* success */); + } } - // Load independently of success or failure to keep up to date with whatever - // has happened on the authpolicyd / session manager side. + // Load independently of success or failure to keep in sync with the state in + // session manager. This cancels any potentially running Load() operations + // thus it is guaranteed that at the next OnStoreLoaded() invocation the + // policy is up-to-date with what was fetched. store_->Load(); } +void ActiveDirectoryPolicyManager::OnBlockingFetchTimeout() { + DCHECK(waiting_for_initial_policy_fetch_); + LOG(WARNING) << "Timed out while waiting for the policy fetch. " + << "The session will start with the cached policy."; + CancelWaitForInitialPolicy(false); +} + +void ActiveDirectoryPolicyManager::CancelWaitForInitialPolicy(bool success) { + if (!waiting_for_initial_policy_fetch_) + return; + + initial_policy_timeout_.Stop(); + + // If the conditions to continue profile initialization are not met, the user + // session is exited and initialization is not set as completed. + // TODO(tnagel): Maybe add code to retry policy fetch? + if (!store_->has_policy()) { + // If there's no policy at all (not even cached) the user session must not + // continue. + LOG(ERROR) << "Policy could not be obtained. " + << "Aborting profile initialization"; + // Prevent duplicate exit session calls. + if (exit_session_) { + std::move(exit_session_).Run(); + } + return; + } + if (!success && !initial_policy_fetch_may_fail_) { + LOG(ERROR) << "Policy fetch failed for the user. " + << "Aborting profile initialization"; + // Prevent duplicate exit session calls. + if (exit_session_) { + std::move(exit_session_).Run(); + } + return; + } + + // Set initialization complete. + waiting_for_initial_policy_fetch_ = false; + + // Publish policy (even though it hasn't changed) in order to signal load + // complete on the ConfigurationPolicyProvider interface. + PublishPolicy(); +} + } // namespace policy
diff --git a/chrome/browser/chromeos/policy/active_directory_policy_manager.h b/chrome/browser/chromeos/policy/active_directory_policy_manager.h index 46cf742..5502fb82b 100644 --- a/chrome/browser/chromeos/policy/active_directory_policy_manager.h +++ b/chrome/browser/chromeos/policy/active_directory_policy_manager.h
@@ -7,8 +7,11 @@ #include <memory> +#include "base/bind.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/time/time.h" +#include "base/timer/timer.h" #include "components/policy/core/common/cloud/cloud_policy_store.h" #include "components/policy/core/common/configuration_policy_provider.h" #include "components/policy/core/common/policy_scheduler.h" @@ -18,9 +21,11 @@ // ConfigurationPolicyProvider for device or user policy from Active Directory. // The choice of constructor determines whether device or user policy is -// provided. The policy is fetched from the Domain Controller by authpolicyd -// which stores it in session manager and from where it is loaded by -// ActiveDirectoryPolicyManager. +// provided. +// Data flow: Triggered by DoPolicyFetch(), policy is fetched by authpolicyd and +// stored in session manager with completion indicated by OnPolicyFetched(). +// From there policy load from session manager is triggered, completion of which +// is notified via OnStoreLoaded()/OnStoreError(). class ActiveDirectoryPolicyManager : public ConfigurationPolicyProvider, public CloudPolicyStore::Observer { public: @@ -33,6 +38,8 @@ // Create manager for |accound_id| user policy. static std::unique_ptr<ActiveDirectoryPolicyManager> CreateForUserPolicy( const AccountId& account_id, + base::TimeDelta initial_policy_fetch_timeout, + base::OnceClosure exit_session, std::unique_ptr<CloudPolicyStore> store); // ConfigurationPolicyProvider: @@ -47,10 +54,25 @@ CloudPolicyStore* store() const { return store_.get(); } + // Helper function to force a policy fetch timeout. + void ForceTimeoutForTest(); + private: - // |account_id| specifies the user to manage policy for. If |account_id| is + // |account_id| specifies the user to manage policy for. If |account_id| is // empty, device policy is managed. + // + // The following applies to user policy only: If + // |initial_policy_fetch_timeout| is non-zero, IsInitializationComplete() is + // forced to false until either there has been a successful policy fetch from + // the server and a subsequent successful load from session manager or + // |initial_policy_fetch_timeout| has expired and there has been a successful + // load from session manager. The timeout may be set to TimeDelta::Max() to + // enforce successful policy fetch. In case the conditions for signaling + // initialization complete are not met, the user session is aborted by calling + // |exit_session|. ActiveDirectoryPolicyManager(const AccountId& account_id, + base::TimeDelta initial_policy_fetch_timeout, + base::OnceClosure exit_session, std::unique_ptr<CloudPolicyStore> store); // Publish the policy that's currently cached in the store. @@ -58,14 +80,49 @@ // Calls into authpolicyd to fetch policy. Reports success or failure via // |callback|. - void DoFetch(PolicyScheduler::TaskCallback callback); + void DoPolicyFetch(PolicyScheduler::TaskCallback callback); - // Called by scheduler with result of policy fetch. + // Called by scheduler with result of policy fetch. This covers policy + // download, parsing and storing into session manager. (To access and publish + // the policy, the store needs to be reloaded from session manager.) void OnPolicyFetched(bool success); - const AccountId account_id_; - std::unique_ptr<CloudPolicyStore> store_; + // Called when |initial_policy_timeout_| times out, to cancel the blocking + // wait for the initial policy fetch. + void OnBlockingFetchTimeout(); + // Cancels waiting for the initial policy fetch/load and flags the + // ConfigurationPolicyProvider ready (assuming all other initialization tasks + // have completed) or exits the session in case the requirements to continue + // have not been met. |success| denotes whether the policy fetch was + // successful. + void CancelWaitForInitialPolicy(bool success); + + const AccountId account_id_; + + // Whether we're waiting for a policy fetch to complete before reporting + // IsInitializationComplete(). + bool waiting_for_initial_policy_fetch_; + + // Whether the user session is continued in case of failure of initial policy + // fetch. + bool initial_policy_fetch_may_fail_; + + // Whether policy fetch has ever been reported as completed by authpolicyd. + bool fetch_ever_completed_ = false; + + // Whether policy fetch has ever been reported as successful by authpolicyd. + bool fetch_ever_succeeded_ = false; + + // A timer that puts a hard limit on the maximum time to wait for the initial + // policy fetch/load. + base::Timer initial_policy_timeout_{false /* retain_user_task */, + false /* is_repeating */}; + + // Callback to exit the session. + base::OnceClosure exit_session_; + + std::unique_ptr<CloudPolicyStore> store_; std::unique_ptr<PolicyScheduler> scheduler_; // Must be last member.
diff --git a/chrome/browser/chromeos/policy/active_directory_policy_manager_unittest.cc b/chrome/browser/chromeos/policy/active_directory_policy_manager_unittest.cc new file mode 100644 index 0000000..d473ca4b --- /dev/null +++ b/chrome/browser/chromeos/policy/active_directory_policy_manager_unittest.cc
@@ -0,0 +1,432 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/policy/active_directory_policy_manager.h" + +#include <memory> +#include <string> +#include <utility> + +#include "base/bind.h" +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" +#include "chromeos/dbus/auth_policy_client.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "components/policy/core/common/cloud/mock_cloud_policy_store.h" +#include "components/policy/core/common/schema_registry.h" +#include "components/signin/core/account_id/account_id.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class TestAuthPolicyClient : public chromeos::AuthPolicyClient { + public: + void Init(dbus::Bus* bus) override { NOTIMPLEMENTED(); } + + void JoinAdDomain(const std::string& machine_name, + const std::string& user_principal_name, + int password_fd, + JoinCallback callback) override { + NOTIMPLEMENTED(); + } + + void AuthenticateUser(const std::string& user_principal_name, + const std::string& object_guid, + int password_fd, + AuthCallback callback) override { + NOTIMPLEMENTED(); + } + + void GetUserStatus(const std::string& object_guid, + GetUserStatusCallback callback) override { + NOTIMPLEMENTED(); + } + + void RefreshDevicePolicy(RefreshPolicyCallback callback) override { + NOTIMPLEMENTED(); + } + + void RefreshUserPolicy(const AccountId& account_id, + RefreshPolicyCallback callback) override { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), + refresh_user_policy_callback_success_)); + } + + void SetRefreshUserPolicyCallbackSuccess(bool success) { + refresh_user_policy_callback_success_ = success; + } + + private: + bool refresh_user_policy_callback_success_ = true; +}; + +} // namespace + +namespace policy { + +// Note that session exit is asynchronous and thus ActiveDirectoryPolicyManager +// still needs to react reasonably to events happening after session exit has +// been fired. +class ActiveDirectoryPolicyManagerTest : public testing::Test { + public: + ActiveDirectoryPolicyManagerTest() { + auto mock_client_unique_ptr = base::MakeUnique<TestAuthPolicyClient>(); + mock_client_ = mock_client_unique_ptr.get(); + chromeos::DBusThreadManager::GetSetterForTesting()->SetAuthPolicyClient( + std::move(mock_client_unique_ptr)); + } + + ~ActiveDirectoryPolicyManagerTest() override { + EXPECT_EQ(session_exit_expected_, session_exited_); + policy_manager_->Shutdown(); + } + + protected: + // Expect that session exit will be called below. (Must only be called once.) + void ExpectSessionExit() { + ASSERT_FALSE(session_exit_expected_); + EXPECT_FALSE(session_exited_); + session_exit_expected_ = true; + } + + // Expect that session exit has been called above. (Must only be called after + // ExpectSessionExit().) + void ExpectSessionExited() { + ASSERT_TRUE(session_exit_expected_); + EXPECT_TRUE(session_exited_); + } + + // Closure to exit the session. + void ExitSession() { + EXPECT_TRUE(session_exit_expected_); + session_exited_ = true; + } + + bool session_exited_ = false; + bool session_exit_expected_ = false; + + // To be handed over to ActiveDirectoryPolicyManager. + base::OnceClosure exit_session_{ + base::BindOnce(&ActiveDirectoryPolicyManagerTest::ExitSession, + base::Unretained(this))}; + + // To be handed over to ActiveDirectoryPolicyManager ... + std::unique_ptr<MockCloudPolicyStore> mock_store_unique_ptr_{ + base::MakeUnique<MockCloudPolicyStore>()}; + + // ... but keeping a non-owned pointer. + MockCloudPolicyStore* mock_store_{mock_store_unique_ptr_.get()}; + + // Owned by DBusThreadManager. + TestAuthPolicyClient* mock_client_; + + SchemaRegistry schema_registry_; + + // Initialized by the individual tests but owned by the test class so that it + // can be shut down automatically after the test has run. + std::unique_ptr<ActiveDirectoryPolicyManager> policy_manager_; + + private: + base::test::ScopedTaskEnvironment scoped_task_environment_; +}; + +TEST_F(ActiveDirectoryPolicyManagerTest, DontWait) { + policy_manager_ = ActiveDirectoryPolicyManager::CreateForUserPolicy( + AccountId::AdFromUserEmailObjGuid("bla", "ble"), base::TimeDelta(), + std::move(exit_session_), std::move(mock_store_unique_ptr_)); + EXPECT_TRUE(policy_manager_); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Configure mock policy fetch to fail. + mock_client_->SetRefreshUserPolicyCallbackSuccess(false); + + // Trigger mock policy fetch from authpolicyd. + policy_manager_->Init(&schema_registry_); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Simulate failed store load. Initialization is reported complete at this + // point. + mock_store_->NotifyStoreError(); + EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Process reply for mock policy fetch. + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Simulate failed store load. + mock_store_->NotifyStoreError(); + EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); +} + +// If the initial fetch timeout is infinite, initialization is only complete +// after policy has been fetched and after that has been loaded. +TEST_F(ActiveDirectoryPolicyManagerTest, + WaitInfinite_LoadSuccess_FetchSuccess) { + policy_manager_ = ActiveDirectoryPolicyManager::CreateForUserPolicy( + AccountId::AdFromUserEmailObjGuid("bla", "ble"), base::TimeDelta::Max(), + std::move(exit_session_), std::move(mock_store_unique_ptr_)); + ASSERT_TRUE(policy_manager_); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Configure mock policy fetch to succeed. + mock_client_->SetRefreshUserPolicyCallbackSuccess(true); + + // Trigger mock policy fetch from authpolicyd. + policy_manager_->Init(&schema_registry_); + + // Simulate successful store load. + mock_store_->policy_ = base::MakeUnique<enterprise_management::PolicyData>(); + mock_store_->NotifyStoreLoaded(); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Process reply for mock policy fetch. + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Simulate successful store load. At this point initialization is complete. + mock_store_->NotifyStoreLoaded(); + EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); +} + +// If the initial fetch timeout is infinite, initialization does not complete if +// load after fetch fails. +TEST_F(ActiveDirectoryPolicyManagerTest, + WaitInfinite_LoadSuccess_FetchSuccess_LoadFail) { + policy_manager_ = ActiveDirectoryPolicyManager::CreateForUserPolicy( + AccountId::AdFromUserEmailObjGuid("bla", "ble"), base::TimeDelta::Max(), + std::move(exit_session_), std::move(mock_store_unique_ptr_)); + ASSERT_TRUE(policy_manager_); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Configure mock policy fetch to succeed. + mock_client_->SetRefreshUserPolicyCallbackSuccess(true); + + // Trigger mock policy fetch from authpolicyd. + policy_manager_->Init(&schema_registry_); + + // Simulate successful store load. + mock_store_->policy_ = base::MakeUnique<enterprise_management::PolicyData>(); + mock_store_->NotifyStoreLoaded(); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Process reply for mock policy fetch. + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + ExpectSessionExit(); + + // Simulate failed store load. + mock_store_->NotifyStoreError(); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + ExpectSessionExited(); + + // Simulate successful store load. + mock_store_->NotifyStoreLoaded(); + EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); +} + +// If the initial fetch timeout is infinite, failure in policy fetch prevents +// initialization from finishing, ever. +TEST_F(ActiveDirectoryPolicyManagerTest, WaitInfinite_LoadSuccess_FetchFail) { + policy_manager_ = ActiveDirectoryPolicyManager::CreateForUserPolicy( + AccountId::AdFromUserEmailObjGuid("bla", "ble"), base::TimeDelta::Max(), + std::move(exit_session_), std::move(mock_store_unique_ptr_)); + ASSERT_TRUE(policy_manager_); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Configure mock policy fetch to fail. + mock_client_->SetRefreshUserPolicyCallbackSuccess(false); + + // Trigger mock policy fetch from authpolicyd. + policy_manager_->Init(&schema_registry_); + + // Simulate successful store load. + mock_store_->policy_ = base::MakeUnique<enterprise_management::PolicyData>(); + mock_store_->NotifyStoreLoaded(); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + ExpectSessionExit(); + + // Process reply for mock policy fetch. + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + ExpectSessionExited(); + + // Simulate successful store load. + mock_store_->NotifyStoreLoaded(); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); +} + +// If the initial fetch timeout is not infinite, we're in best-effort mode but +// still require the policy load to succeed so that there's *some* policy +// present (though possibly outdated). +TEST_F(ActiveDirectoryPolicyManagerTest, WaitFinite_LoadSuccess_FetchFail) { + policy_manager_ = ActiveDirectoryPolicyManager::CreateForUserPolicy( + AccountId::AdFromUserEmailObjGuid("bla", "ble"), + base::TimeDelta::FromDays(365), std::move(exit_session_), + std::move(mock_store_unique_ptr_)); + ASSERT_TRUE(policy_manager_); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Configure mock policy fetch to fail. + mock_client_->SetRefreshUserPolicyCallbackSuccess(false); + + // Trigger mock policy fetch from authpolicyd. + policy_manager_->Init(&schema_registry_); + + // Simulate successful store load. + mock_store_->policy_ = base::MakeUnique<enterprise_management::PolicyData>(); + mock_store_->NotifyStoreLoaded(); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Process reply for mock policy fetch. At this point initialization is + // complete (we have waited for the fetch but now that we know it has failed + // we continue). + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Simulate successful store load. + mock_store_->NotifyStoreLoaded(); + EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); +} + +// If the initial fetch timeout is not infinite, we're in best-effort mode but +// still require the policy load to succeed so that there's *some* policy +// present (though possibly outdated). Here the sequence is inverted: Fetch +// returns before load. +TEST_F(ActiveDirectoryPolicyManagerTest, WaitFinite_FetchFail_LoadSuccess) { + policy_manager_ = ActiveDirectoryPolicyManager::CreateForUserPolicy( + AccountId::AdFromUserEmailObjGuid("bla", "ble"), + base::TimeDelta::FromDays(365), std::move(exit_session_), + std::move(mock_store_unique_ptr_)); + ASSERT_TRUE(policy_manager_); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Configure mock policy fetch to fail. + mock_client_->SetRefreshUserPolicyCallbackSuccess(false); + + // Trigger mock policy fetch from authpolicyd. + policy_manager_->Init(&schema_registry_); + + // Process reply for mock policy fetch. + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Simulate successful store load. + mock_store_->policy_ = base::MakeUnique<enterprise_management::PolicyData>(); + mock_store_->NotifyStoreLoaded(); + EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); +} + +// If the initial fetch timeout is not infinite, we're in best-effort mode but +// if we can't load existing policy from disk we have to give up. +TEST_F(ActiveDirectoryPolicyManagerTest, WaitFinite_LoadFail_FetchFail) { + policy_manager_ = ActiveDirectoryPolicyManager::CreateForUserPolicy( + AccountId::AdFromUserEmailObjGuid("bla", "ble"), + base::TimeDelta::FromDays(365), std::move(exit_session_), + std::move(mock_store_unique_ptr_)); + ASSERT_TRUE(policy_manager_); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Configure mock policy fetch to fail. + mock_client_->SetRefreshUserPolicyCallbackSuccess(false); + + // Trigger mock policy fetch from authpolicyd. + policy_manager_->Init(&schema_registry_); + + // Simulate failed store load. + mock_store_->NotifyStoreError(); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + ExpectSessionExit(); + + // Process reply for mock policy fetch. + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + ExpectSessionExited(); + + // Simulate successful store load. + mock_store_->policy_ = base::MakeUnique<enterprise_management::PolicyData>(); + mock_store_->NotifyStoreLoaded(); + EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); +} + +// If the initial fetch timeout is not infinite, we're in best-effort mode and +// upon timeout initialization is complete if any policy could be loaded from +// disk. +TEST_F(ActiveDirectoryPolicyManagerTest, WaitFinite_LoadSuccess_FetchTimeout) { + policy_manager_ = ActiveDirectoryPolicyManager::CreateForUserPolicy( + AccountId::AdFromUserEmailObjGuid("bla", "ble"), + base::TimeDelta::FromDays(365), std::move(exit_session_), + std::move(mock_store_unique_ptr_)); + ASSERT_TRUE(policy_manager_); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Configure mock policy fetch to fail. + mock_client_->SetRefreshUserPolicyCallbackSuccess(false); + + // Trigger mock policy fetch from authpolicyd. + policy_manager_->Init(&schema_registry_); + + // Simulate successful store load. + mock_store_->policy_ = base::MakeUnique<enterprise_management::PolicyData>(); + mock_store_->NotifyStoreLoaded(); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Simulate policy fetch timeout. + policy_manager_->ForceTimeoutForTest(); + EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Process reply for mock policy fetch. + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Simulate failed store load. + mock_store_->NotifyStoreError(); + EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); +} + +// If the initial fetch timeout is not infinite, we're in best-effort mode but +// without a successful policy load we still can't continue. +TEST_F(ActiveDirectoryPolicyManagerTest, WaitFinite_LoadTimeout_FetchTimeout) { + policy_manager_ = ActiveDirectoryPolicyManager::CreateForUserPolicy( + AccountId::AdFromUserEmailObjGuid("bla", "ble"), + base::TimeDelta::FromDays(365), std::move(exit_session_), + std::move(mock_store_unique_ptr_)); + ASSERT_TRUE(policy_manager_); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Configure mock policy fetch to fail. + mock_client_->SetRefreshUserPolicyCallbackSuccess(false); + + // Trigger mock policy fetch from authpolicyd. + policy_manager_->Init(&schema_registry_); + + ExpectSessionExit(); + + // Simulate policy fetch timeout. + policy_manager_->ForceTimeoutForTest(); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + ExpectSessionExited(); + + // Process reply for mock policy fetch. + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + + // Simulate successful store load. + mock_store_->policy_ = base::MakeUnique<enterprise_management::PolicyData>(); + mock_store_->NotifyStoreLoaded(); + EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); +} + +} // namespace policy
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc index 2edac9ed..fe72e87 100644 --- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc +++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc
@@ -87,7 +87,6 @@ std::unique_ptr<CloudPolicyStore> store, std::unique_ptr<CloudExternalDataManager> external_data_manager, const base::FilePath& component_policy_cache_path, - bool wait_for_policy_fetch, base::TimeDelta initial_policy_fetch_timeout, const scoped_refptr<base::SequencedTaskRunner>& task_runner, const scoped_refptr<base::SequencedTaskRunner>& file_task_runner, @@ -101,18 +100,16 @@ store_(std::move(store)), external_data_manager_(std::move(external_data_manager)), component_policy_cache_path_(component_policy_cache_path), - wait_for_policy_fetch_(wait_for_policy_fetch) { + waiting_for_initial_policy_fetch_( + !initial_policy_fetch_timeout.is_zero()) { time_init_started_ = base::Time::Now(); - // Caller must pass a non-zero policy_fetch_timeout iff - // |wait_for_policy_fetch| is true. - DCHECK_NE(wait_for_policy_fetch_, initial_policy_fetch_timeout.is_zero()); - allow_failed_policy_fetches_ = + initial_policy_fetch_may_fail_ = base::CommandLine::ForCurrentProcess()->HasSwitch( chromeos::switches::kAllowFailedPolicyFetchForTest) || !initial_policy_fetch_timeout.is_max(); // No need to set the timer when the timeout is infinite. - if (wait_for_policy_fetch_ && !initial_policy_fetch_timeout.is_max()) { + if (waiting_for_initial_policy_fetch_ && initial_policy_fetch_may_fail_) { policy_fetch_timeout_.Start( FROM_HERE, initial_policy_fetch_timeout, @@ -174,10 +171,10 @@ // store has already been loaded and contains a valid policy - the // registration setup in this case is performed by the CloudPolicyService // that is instantiated inside the CloudPolicyCore::Connect() method call. - // If that's the case and |wait_for_policy_fetch_| is true, then the policy - // fetch needs to be issued (it happens otherwise after the client - // registration is finished, in OnRegistrationStateChanged()). - if (client()->is_registered() && wait_for_policy_fetch_) { + // If that's the case and |waiting_for_initial_policy_fetch_| is true, then + // the policy fetch needs to be issued (it happens otherwise after the + // client registration is finished, in OnRegistrationStateChanged()). + if (client()->is_registered() && waiting_for_initial_policy_fetch_) { service()->RefreshPolicy( base::Bind(&UserCloudPolicyManagerChromeOS::CancelWaitForPolicyFetch, base::Unretained(this))); @@ -230,7 +227,7 @@ if (!CloudPolicyManager::IsInitializationComplete(domain)) return false; if (domain == POLICY_DOMAIN_CHROME) - return !wait_for_policy_fetch_; + return !waiting_for_initial_policy_fetch_; return true; } @@ -246,25 +243,27 @@ // If the CloudPolicyClient isn't registered at this stage then it needs an // OAuth token for the initial registration. // - // If |wait_for_policy_fetch_| is true then Profile initialization is blocking - // on the initial policy fetch, so the token must be fetched immediately. - // In that case, the signin Profile is used to authenticate a Gaia request to - // fetch a refresh token, and then the policy token is fetched. + // If |waiting_for_initial_policy_fetch_| is true then Profile initialization + // is blocking on the initial policy fetch, so the token must be fetched + // immediately. In that case, the signin Profile is used to authenticate a + // Gaia request to fetch a refresh token, and then the policy token is + // fetched. // - // If |wait_for_policy_fetch_| is false then the UserCloudPolicyTokenForwarder - // service will eventually call OnAccessTokenAvailable() once an access token - // is available. That call may have already happened while waiting for - // initialization of the CloudPolicyService, so in that case check if an - // access token is already available. + // If |waiting_for_initial_policy_fetch_| is false then the + // UserCloudPolicyTokenForwarder service will eventually call + // OnAccessTokenAvailable() once an access token is available. That call may + // have already happened while waiting for initialization of the + // CloudPolicyService, so in that case check if an access token is already + // available. if (!client()->is_registered()) { - if (wait_for_policy_fetch_) { + if (waiting_for_initial_policy_fetch_) { FetchPolicyOAuthToken(); } else if (!access_token_.empty()) { OnAccessTokenAvailable(access_token_); } } - if (!wait_for_policy_fetch_) { + if (!waiting_for_initial_policy_fetch_) { // If this isn't blocking on a policy fetch then // CloudPolicyManager::OnStoreLoaded() already published the cached policy. // Start the refresh scheduler now, which will eventually refresh the @@ -285,7 +284,7 @@ CloudPolicyClient* cloud_policy_client) { DCHECK_EQ(client(), cloud_policy_client); - if (wait_for_policy_fetch_) { + if (waiting_for_initial_policy_fetch_) { time_client_registered_ = base::Time::Now(); if (!time_token_available_.is_null()) { UMA_HISTOGRAM_MEDIUM_TIMES( @@ -310,7 +309,7 @@ void UserCloudPolicyManagerChromeOS::OnClientError( CloudPolicyClient* cloud_policy_client) { DCHECK_EQ(client(), cloud_policy_client); - if (wait_for_policy_fetch_) { + if (waiting_for_initial_policy_fetch_) { UMA_HISTOGRAM_SPARSE_SLOWLY(kUMAInitialFetchClientError, cloud_policy_client->status()); } @@ -404,7 +403,7 @@ const GoogleServiceAuthError& error) { DCHECK(!client()->is_registered()); time_token_available_ = base::Time::Now(); - if (wait_for_policy_fetch_) { + if (waiting_for_initial_policy_fetch_) { UMA_HISTOGRAM_MEDIUM_TIMES(kUMAInitialFetchDelayOAuth2Token, time_token_available_ - time_init_completed_); } @@ -445,14 +444,14 @@ } void UserCloudPolicyManagerChromeOS::OnBlockingFetchTimeout() { - DCHECK(wait_for_policy_fetch_); + DCHECK(waiting_for_initial_policy_fetch_); LOG(WARNING) << "Timed out while waiting for the policy fetch. " << "The session will start with the cached policy."; CancelWaitForPolicyFetch(false); } void UserCloudPolicyManagerChromeOS::CancelWaitForPolicyFetch(bool success) { - if (!wait_for_policy_fetch_) + if (!waiting_for_initial_policy_fetch_) return; policy_fetch_timeout_.Stop(); @@ -461,7 +460,7 @@ // to go forward after a failed policy fetch, then just return (profile // initialization will not complete). // TODO(atwilson): Add code to retry policy fetching. - if (!success && !allow_failed_policy_fetches_) { + if (!success && !initial_policy_fetch_may_fail_) { LOG(ERROR) << "Policy fetch failed for the user. " "Aborting profile initialization"; // Need to exit the current user, because we've already started this user's @@ -470,10 +469,11 @@ return; } - wait_for_policy_fetch_ = false; + waiting_for_initial_policy_fetch_ = false; + CheckAndPublishPolicy(); - // Now that |wait_for_policy_fetch_| is guaranteed to be false, the scheduler - // can be started. + // Now that |waiting_for_initial_policy_fetch_| is guaranteed to be false, the + // scheduler can be started. StartRefreshSchedulerIfReady(); } @@ -481,7 +481,7 @@ if (core()->refresh_scheduler()) return; // Already started. - if (wait_for_policy_fetch_) + if (waiting_for_initial_policy_fetch_) return; // Still waiting for the initial, blocking fetch. if (!service() || !local_state_)
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h index 1aff359..59444c87 100644 --- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h +++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h
@@ -45,10 +45,10 @@ public CloudPolicyService::Observer, public KeyedService { public: - // If |wait_for_policy_fetch| is true, IsInitializationComplete() is forced to - // false until either there has been a successful policy fetch from the server - // or |initial_policy_fetch_timeout| has expired. (The timeout may be set to - // TimeDelta::Max() to block permanently.) + // If |initial_policy_fetch_timeout| is non-zero, IsInitializationComplete() + // is forced to false until either there has been a successful policy fetch + // from the server or |initial_policy_fetch_timeout| has expired. (The timeout + // may be set to TimeDelta::Max() to block permanently.) // |task_runner| is the runner for policy refresh tasks. // |file_task_runner| is used for file operations. Currently this must be the // FILE BrowserThread. @@ -58,7 +58,6 @@ std::unique_ptr<CloudPolicyStore> store, std::unique_ptr<CloudExternalDataManager> external_data_manager, const base::FilePath& component_policy_cache_path, - bool wait_for_policy_fetch, base::TimeDelta initial_policy_fetch_timeout, const scoped_refptr<base::SequencedTaskRunner>& task_runner, const scoped_refptr<base::SequencedTaskRunner>& file_task_runner, @@ -127,19 +126,19 @@ const GoogleServiceAuthError& error); // Completion handler for the explicit policy fetch triggered on startup in - // case |wait_for_policy_fetch_| is true. |success| is true if the fetch was - // successful. + // case |waiting_for_initial_policy_fetch_| is true. |success| is true if the + // fetch was successful. void OnInitialPolicyFetchComplete(bool success); - // Called when |policy_fetch_timeout_| times out, to cancel the blocking - // wait for the initial policy fetch. + // Called when |policy_fetch_timeout_| times out, to cancel the blocking wait + // for the initial policy fetch. void OnBlockingFetchTimeout(); - // Cancels waiting for the policy fetch and flags the + // Cancels waiting for the initial policy fetch and flags the // ConfigurationPolicyProvider ready (assuming all other initialization tasks - // have completed). Pass |true| if policy fetch was successful (either - // because policy was successfully fetched, or if DMServer has notified us - // that the user is not managed). + // have completed). Pass |true| if policy fetch was successful (either because + // policy was successfully fetched, or if DMServer has notified us that the + // user is not managed). void CancelWaitForPolicyFetch(bool success); void StartRefreshSchedulerIfReady(); @@ -156,18 +155,18 @@ // Path where policy for components will be cached. base::FilePath component_policy_cache_path_; - // Whether to wait for a policy fetch to complete before reporting + // Whether we're waiting for a policy fetch to complete before reporting // IsInitializationComplete(). - bool wait_for_policy_fetch_; + bool waiting_for_initial_policy_fetch_; - // Whether we should allow policy fetches to fail, or wait forever until they - // succeed (typically we won't allow them to fail until we have loaded policy - // at least once). - bool allow_failed_policy_fetches_; + // Whether the user session is continued in case of failure of initial policy + // fetch. + bool initial_policy_fetch_may_fail_; // A timer that puts a hard limit on the maximum time to wait for the initial // policy fetch. - base::Timer policy_fetch_timeout_{false, false}; + base::Timer policy_fetch_timeout_{false /* retain_user_task */, + false /* is_repeating */}; // The pref service to pass to the refresh scheduler on initialization. PrefService* local_state_;
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc index d8f7558..ccb1d1d 100644 --- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc +++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
@@ -88,17 +88,16 @@ public: // Note: This method has to be public, so that a pointer to it may be obtained // in the test. - void MakeManagerWithPreloadedStore(bool wait_for_fetch, - int fetch_timeout_seconds) { + void MakeManagerWithPreloadedStore(int fetch_timeout_seconds) { std::unique_ptr<MockCloudPolicyStore> store = base::MakeUnique<MockCloudPolicyStore>(); store->policy_.reset(new em::PolicyData(policy_data_)); store->policy_map_.CopyFrom(policy_map_); store->NotifyStoreLoaded(); - CreateManager(std::move(store), wait_for_fetch, fetch_timeout_seconds); + CreateManager(std::move(store), fetch_timeout_seconds); // The manager gets already initialized by this point if the store is // initialized and there is no blocking for policy fetch. - EXPECT_NE(wait_for_fetch, + EXPECT_NE(fetch_timeout_seconds != 0, manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); InitAndConnectManager(); EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete()); @@ -179,11 +178,11 @@ profile_manager_->DeleteTestingProfile(chrome::kInitialProfile); } - void MakeManagerWithEmptyStore(bool wait_for_fetch, int fetch_timeout) { + void MakeManagerWithEmptyStore(int fetch_timeout) { std::unique_ptr<MockCloudPolicyStore> store = base::MakeUnique<MockCloudPolicyStore>(); EXPECT_CALL(*store, Load()); - CreateManager(std::move(store), wait_for_fetch, fetch_timeout); + CreateManager(std::move(store), fetch_timeout); EXPECT_FALSE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); InitAndConnectManager(); Mock::VerifyAndClearExpectations(store_); @@ -339,7 +338,6 @@ private: void CreateManager(std::unique_ptr<MockCloudPolicyStore> store, - bool wait_for_fetch, int fetch_timeout_seconds) { store_ = store.get(); external_data_manager_ = new MockCloudExternalDataManager; @@ -347,11 +345,10 @@ manager_.reset(new UserCloudPolicyManagerChromeOS( std::move(store), base::WrapUnique<MockCloudExternalDataManager>(external_data_manager_), - base::FilePath(), wait_for_fetch, - base::TimeDelta::FromSeconds(fetch_timeout_seconds), task_runner_, - task_runner_, task_runner_)); + base::FilePath(), base::TimeDelta::FromSeconds(fetch_timeout_seconds), + task_runner_, task_runner_, task_runner_)); manager_->AddObserver(&observer_); - should_create_token_forwarder_ = !wait_for_fetch; + should_create_token_forwarder_ = (fetch_timeout_seconds == 0); } void InitAndConnectManager() { @@ -381,7 +378,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFirstFetch) { // Tests the initialization of a manager whose Profile is waiting for the // initial fetch, when the policy cache is empty. - ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(true, 1000)); + ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(1000)); // Initialize the CloudPolicyService without any stored data. EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); @@ -404,7 +401,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingRefreshFetch) { // Tests the initialization of a manager whose Profile is waiting for the // initial fetch, when a previously cached policy and DMToken already exist. - ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(true, 1000)); + ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(1000)); // Set the initially cached data and initialize the CloudPolicyService. // The initial policy fetch is issued using the cached DMToken. @@ -425,13 +422,13 @@ // performed by the manager). FetchPolicy(base::Bind( &UserCloudPolicyManagerChromeOSTest::MakeManagerWithPreloadedStore, - base::Unretained(this), true, 1000)); + base::Unretained(this), 1000)); } TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchStoreError) { // Tests the initialization of a manager whose Profile is waiting for the // initial fetch, when the initial store load fails. - ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(true, 1000)); + ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(1000)); // Initialize the CloudPolicyService without any stored data. EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); @@ -454,7 +451,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchOAuthError) { // Tests the initialization of a manager whose Profile is waiting for the // initial fetch, when the OAuth2 token fetch fails. - ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(true, 1000)); + ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(1000)); // Initialize the CloudPolicyService without any stored data. EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); @@ -483,7 +480,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchRegisterError) { // Tests the initialization of a manager whose Profile is waiting for the // initial fetch, when the device management registration fails. - ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(true, 1000)); + ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(1000)); // Initialize the CloudPolicyService without any stored data. EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); @@ -509,7 +506,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchPolicyFetchError) { // Tests the initialization of a manager whose Profile is waiting for the // initial fetch, when the policy fetch request fails. - ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(true, 1000)); + ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(1000)); // Initialize the CloudPolicyService without any stored data. EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); @@ -548,7 +545,7 @@ } TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchTimeout) { - ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(true, 1000)); + ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(1000)); // Initialize the CloudPolicyService without any stored data. EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); @@ -567,7 +564,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, NonBlockingFirstFetch) { // Tests the first policy fetch request by a Profile that isn't managed. - ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(false, 0)); + ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(0)); // Initialize the CloudPolicyService without any stored data. Since the // manager is not waiting for the initial fetch, it will become initialized @@ -613,7 +610,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, NonBlockingRefreshFetch) { // Tests a non-blocking initial policy fetch for a Profile that already has // a cached DMToken. - ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(false, 0)); + ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(0)); // Set the initially cached data and initialize the CloudPolicyService. // The initial policy fetch is issued using the cached DMToken. @@ -639,7 +636,7 @@ // fetch, when a previously cached policy and DMToken are already loaded // before the manager is constructed. The manager gets initialized straight // away after the construction. - MakeManagerWithPreloadedStore(false, 0); + MakeManagerWithPreloadedStore(0); EXPECT_TRUE(manager_->policies().Equals(expected_bundle_)); }
diff --git a/chrome/browser/chromeos/policy/user_policy_manager_factory_chromeos.cc b/chrome/browser/chromeos/policy/user_policy_manager_factory_chromeos.cc index 4a3d4807..f3dd27ff 100644 --- a/chrome/browser/chromeos/policy/user_policy_manager_factory_chromeos.cc +++ b/chrome/browser/chromeos/policy/user_policy_manager_factory_chromeos.cc
@@ -26,6 +26,7 @@ #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/install_attributes.h" +#include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/policy/schema_registry_service.h" #include "chrome/browser/policy/schema_registry_service_factory.h" #include "chrome/browser/profiles/profile.h" @@ -261,8 +262,9 @@ if (is_active_directory) { std::unique_ptr<ActiveDirectoryPolicyManager> manager = - ActiveDirectoryPolicyManager::CreateForUserPolicy(account_id, - std::move(store)); + ActiveDirectoryPolicyManager::CreateForUserPolicy( + account_id, initial_policy_fetch_timeout, + base::BindOnce(&chrome::AttemptUserExit), std::move(store)); manager->Init( SchemaRegistryServiceFactory::GetForContext(profile)->registry()); @@ -272,9 +274,9 @@ std::unique_ptr<UserCloudPolicyManagerChromeOS> manager = base::MakeUnique<UserCloudPolicyManagerChromeOS>( std::move(store), std::move(external_data_manager), - component_policy_cache_dir, wait_for_policy_fetch, - initial_policy_fetch_timeout, base::ThreadTaskRunnerHandle::Get(), - file_task_runner, io_task_runner); + component_policy_cache_dir, initial_policy_fetch_timeout, + base::ThreadTaskRunnerHandle::Get(), file_task_runner, + io_task_runner); // TODO(tnagel): Enable whitelist for Active Directory. bool wildcard_match = false;
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 1379b7be..256ac73 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -381,6 +381,11 @@ const char kEnableTokenBindingName[] = "Token Binding."; const char kEnableTokenBindingDescription[] = "Enable Token Binding support."; +const char kEnableUsernameCorrectionName[] = "Enable username correction"; +const char kEnableUsernameCorrectionDescription[] = + "While on the pending password state, add an edit button to the bubble so " + "that user can edit the username."; + const char kEnableUseZoomForDsfName[] = "Use Blink's zoom for device scale factor."; const char kEnableUseZoomForDsfDescription[] = @@ -2696,6 +2701,11 @@ "Enables inspection of native UI elements. For local inspection use " "chrome://inspect#other"; +const char kUseCrosMidiServiceName[] = "Use Chrome OS MIDI Service"; +const char kUseCrosMidiServiceNameDescription[] = + "Use Chrome OS MIDI Service for Web MIDI and allow ARC to support Android " + "MIDI."; + const char kMultideviceName[] = "Enable multidevice features"; const char kMultideviceDescription[] = "Enables UI for controlling multidevice features.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index a0ec35a..cfee3e4 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -257,6 +257,9 @@ extern const char kEnableTokenBindingName[]; extern const char kEnableTokenBindingDescription[]; +extern const char kEnableUsernameCorrectionName[]; +extern const char kEnableUsernameCorrectionDescription[]; + extern const char kEnableUseZoomForDsfName[]; extern const char kEnableUseZoomForDsfDescription[]; extern const char kEnableUseZoomForDsfChoiceDefault[]; @@ -1396,6 +1399,9 @@ extern const char kUiDevToolsName[]; extern const char kUiDevToolsDescription[]; +extern const char kUseCrosMidiServiceName[]; +extern const char kUseCrosMidiServiceNameDescription[]; + extern const char kUseMusName[]; extern const char kUseMusDescription[]; extern const char kEnableMashDescription[];
diff --git a/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.html b/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.html index ca47f6a..6f7d2eff 100644 --- a/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.html +++ b/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.html
@@ -3,9 +3,7 @@ <head> <meta charset="utf-8"> <link rel="import" href="chrome://resources/html/polymer.html"> - <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> - <link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> <link rel="import" href="signin_shared_css.html"> <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> @@ -17,20 +15,6 @@ -webkit-margin-start: 0; } </if> - /* TODO(dbeam): de-duplicate this style with MD Settings. */ - paper-checkbox { - --paper-checkbox-checked-color: var(--google-blue-500); - --paper-checkbox-label-color: inherit; - --paper-checkbox-label-spacing: 22px; - --paper-checkbox-size: 16px; - --paper-checkbox-unchecked-color: var(--paper-grey-600); - -webkit-margin-start: 2px; - } -<if expr="is_macosx"> - html:not(.focus-allowed) paper-checkbox { - --paper-checkbox-ink-size: 0; - } -</if> </style> </head> <body> @@ -72,9 +56,7 @@ <div id="chrome-logo" class="logo"></div> <div> <div class="title">$i18n{syncConfirmationChromeSyncTitle}</div> - <div class="body text"> - $i18nRaw{syncConfirmationChromeSyncBody} - </div> + <div class="body text">$i18n{syncConfirmationChromeSyncBody}</div> </div> </div> <div class="message-container"> @@ -93,11 +75,7 @@ </div> </div> <div class="message-container"> - <div class="body"> - <paper-checkbox id="configure-before-signing-in"> - $i18n{syncConfirmationSyncSettingsLabel} - </paper-checkbox> - </div> + <div class="body">$i18nRaw{syncConfirmationSyncSettingsLinkBody}</div> </div> </div> <div class="details" id="syncDisabledDetails">
diff --git a/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.js b/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.js index 53d6853..5ae5baf 100644 --- a/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.js +++ b/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.js
@@ -6,18 +6,23 @@ 'use strict'; function onConfirm(e) { - chrome.send('confirm', [$('configure-before-signing-in').checked]); + chrome.send('confirm'); } function onUndo(e) { chrome.send('undo'); } + function onGoToSettings(e) { + chrome.send('goToSettings'); + } + function initialize() { document.addEventListener('keydown', onKeyDown); $('confirmButton').addEventListener('click', onConfirm); $('undoButton').addEventListener('click', onUndo); if (loadTimeData.getBoolean('isSyncAllowed')) { + $('settingsLink').addEventListener('click', onGoToSettings); $('profile-picture').addEventListener('load', onPictureLoaded); $('syncDisabledDetails').hidden = true; } else { @@ -32,7 +37,6 @@ function clearFocus() { document.activeElement.blur(); - document.documentElement.classList.add('focus-allowed'); } function setUserImageURL(url) {
diff --git a/chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc b/chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc index 34ef988f..4ada3cac 100644 --- a/chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc +++ b/chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc
@@ -19,6 +19,7 @@ #include "net/cert/signed_certificate_timestamp_and_status.h" #include "net/test/cert_test_util.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" #include "net/test/test_data_directory.h" #include "net/test/url_request/url_request_failed_job.h" @@ -337,26 +338,34 @@ std::unique_ptr<net::test_server::HttpResponse> HandleReportPreflight( const net::test_server::HttpRequest& request) { - num_requests_++; - if (!requests_callback_.is_null()) { - requests_callback_.Run(); - } + handled_preflight_ = true; std::unique_ptr<net::test_server::BasicHttpResponse> http_response( new net::test_server::BasicHttpResponse()); http_response->set_code(net::HTTP_OK); for (const auto& cors_header : cors_headers_) { http_response->AddCustomHeader(cors_header.first, cors_header.second); } + + // If WaitForReportPreflight() has been called, signal that a preflight has + // been handled. Do this after copying |cors_headers_| to the response, + // because tests can mutate |cors_headers_| immediately after + // |preflight_run_loop_| quits. + if (preflight_run_loop_) { + preflight_run_loop_->Quit(); + } + return http_response; } + // Can only be called once per test to wait for a single preflight. void WaitForReportPreflight() { - if (num_requests_ >= 1) { + DCHECK(!preflight_run_loop_) + << "WaitForReportPreflight should only be called once per test"; + if (handled_preflight_) { return; } - base::RunLoop run_loop; - requests_callback_ = run_loop.QuitClosure(); - run_loop.Run(); + preflight_run_loop_ = base::MakeUnique<base::RunLoop>(); + preflight_run_loop_->Run(); } protected: @@ -399,8 +408,11 @@ private: content::TestBrowserThreadBundle thread_bundle_; net::EmbeddedTestServer report_server_; - uint32_t num_requests_ = 0; - base::Closure requests_callback_; + // Set to true when HandleReportPreflight() has been called. Used by + // WaitForReportPreflight() to determine when to just return immediately + // because a preflight has already been handled. + bool handled_preflight_ = false; + std::unique_ptr<base::RunLoop> preflight_run_loop_; std::map<std::string, std::string> cors_headers_{ {"Access-Control-Allow-Origin", "*"}, {"Access-Control-Allow-Methods", "GET,POST"},
diff --git a/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.cc b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.cc index 9427fe30..3f0d19e 100644 --- a/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.cc +++ b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h" +#include <utility> + #include "base/memory/ptr_util.h" #include "chrome/browser/ui/views/ime_driver/remote_text_input_client.h" @@ -28,16 +30,15 @@ input_method_chromeos_->OnCaretBoundsChanged(client_.get()); } -void InputMethodBridge::ProcessKeyEvent( - std::unique_ptr<ui::Event> event, - const ProcessKeyEventCallback& callback) { +void InputMethodBridge::ProcessKeyEvent(std::unique_ptr<ui::Event> event, + ProcessKeyEventCallback callback) { DCHECK(event->IsKeyEvent()); ui::KeyEvent* key_event = event->AsKeyEvent(); if (!key_event->is_char()) { input_method_chromeos_->DispatchKeyEvent(key_event, std::move(callback)); } else { const bool handled = false; - callback.Run(handled); + std::move(callback).Run(handled); } }
diff --git a/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h index 8ca254d..b54608c 100644 --- a/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h +++ b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h
@@ -20,7 +20,7 @@ void OnTextInputTypeChanged(ui::TextInputType text_input_type) override; void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override; void ProcessKeyEvent(std::unique_ptr<ui::Event> key_event, - const ProcessKeyEventCallback& callback) override; + ProcessKeyEventCallback callback) override; void CancelComposition() override; private:
diff --git a/chrome/browser/ui/views/ime_driver/simple_input_method.cc b/chrome/browser/ui/views/ime_driver/simple_input_method.cc index 7ca08882..0dd51a3 100644 --- a/chrome/browser/ui/views/ime_driver/simple_input_method.cc +++ b/chrome/browser/ui/views/ime_driver/simple_input_method.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/ui/views/ime_driver/simple_input_method.h" +#include <utility> + SimpleInputMethod::SimpleInputMethod() {} SimpleInputMethod::~SimpleInputMethod() {} @@ -13,10 +15,9 @@ void SimpleInputMethod::OnCaretBoundsChanged(const gfx::Rect& caret_bounds) {} -void SimpleInputMethod::ProcessKeyEvent( - std::unique_ptr<ui::Event> key_event, - const ProcessKeyEventCallback& callback) { - callback.Run(false); +void SimpleInputMethod::ProcessKeyEvent(std::unique_ptr<ui::Event> key_event, + ProcessKeyEventCallback callback) { + std::move(callback).Run(false); } void SimpleInputMethod::CancelComposition() {}
diff --git a/chrome/browser/ui/views/ime_driver/simple_input_method.h b/chrome/browser/ui/views/ime_driver/simple_input_method.h index 9f666283..f262c21d 100644 --- a/chrome/browser/ui/views/ime_driver/simple_input_method.h +++ b/chrome/browser/ui/views/ime_driver/simple_input_method.h
@@ -20,7 +20,7 @@ void OnTextInputTypeChanged(ui::TextInputType text_input_type) override; void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override; void ProcessKeyEvent(std::unique_ptr<ui::Event> key_event, - const ProcessKeyEventCallback& callback) override; + ProcessKeyEventCallback callback) override; void CancelComposition() override; private:
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc b/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc index 0a99dbb7..ea30744 100644 --- a/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc +++ b/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc
@@ -56,6 +56,9 @@ base::Unretained(this))); web_ui()->RegisterMessageCallback("undo", base::Bind(&SyncConfirmationHandler::HandleUndo, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "goToSettings", base::Bind(&SyncConfirmationHandler::HandleGoToSettings, + base::Unretained(this))); web_ui()->RegisterMessageCallback("initializedWithSize", base::Bind(&SyncConfirmationHandler::HandleInitializedWithSize, base::Unretained(this))); @@ -63,11 +66,12 @@ void SyncConfirmationHandler::HandleConfirm(const base::ListValue* args) { did_user_explicitly_interact = true; - bool configure_sync_first = false; - CHECK(args->GetBoolean(0, &configure_sync_first)); - CloseModalSigninWindow(configure_sync_first - ? LoginUIService::CONFIGURE_SYNC_FIRST - : LoginUIService::SYNC_WITH_DEFAULT_SETTINGS); + CloseModalSigninWindow(LoginUIService::SYNC_WITH_DEFAULT_SETTINGS); +} + +void SyncConfirmationHandler::HandleGoToSettings(const base::ListValue* args) { + did_user_explicitly_interact = true; + CloseModalSigninWindow(LoginUIService::CONFIGURE_SYNC_FIRST); } void SyncConfirmationHandler::HandleUndo(const base::ListValue* args) {
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_handler.h b/chrome/browser/ui/webui/signin/sync_confirmation_handler.h index 7de6334..8953681e 100644 --- a/chrome/browser/ui/webui/signin/sync_confirmation_handler.h +++ b/chrome/browser/ui/webui/signin/sync_confirmation_handler.h
@@ -36,8 +36,7 @@ protected: // Handles "confirm" message from the page. No arguments. // This message is sent when the user confirms that they want complete sign in - // with default sync settings. Passed a single boolean argument: whether to - // configure settings before signing in. + // with default sync settings. virtual void HandleConfirm(const base::ListValue* args); // Handles "undo" message from the page. No arguments. @@ -45,6 +44,12 @@ // dialog, which aborts signin and prevents sync from starting. virtual void HandleUndo(const base::ListValue* args); + // Handles "goToSettings" message from the page. No arguments. + // This message is sent when the user clicks on the "Settings" link in the + // sync confirmation dialog, which completes sign in but takes the user to the + // sync settings page for configuration before starting sync. + virtual void HandleGoToSettings(const base::ListValue* args); + // Handles the web ui message sent when the html content is done being laid // out and it's time to resize the native view hosting it to fit. |args| is // a single integer value for the height the native view should resize to.
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc b/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc index 2627333..c6e6599 100644 --- a/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc +++ b/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc
@@ -43,6 +43,7 @@ using SyncConfirmationHandler::HandleConfirm; using SyncConfirmationHandler::HandleUndo; using SyncConfirmationHandler::HandleInitializedWithSize; + using SyncConfirmationHandler::HandleGoToSettings; using SyncConfirmationHandler::SetUserImageURL; private: @@ -91,7 +92,6 @@ public: SyncConfirmationHandlerTest() : did_user_explicitly_interact(false), web_ui_(new content::TestWebUI) {} - void SetUp() override { BrowserWithTestWindowTest::SetUp(); chrome::NewTab(browser()); @@ -119,10 +119,11 @@ web_ui_.reset(); BrowserWithTestWindowTest::TearDown(); - if (did_user_explicitly_interact) + if (did_user_explicitly_interact) { EXPECT_EQ(0, user_action_tester()->GetActionCount("Signin_Abort_Signin")); - else + } else { EXPECT_EQ(1, user_action_tester()->GetActionCount("Signin_Abort_Signin")); + } } TestingSyncConfirmationHandler* handler() { @@ -316,9 +317,7 @@ EXPECT_FALSE(sync()->IsFirstSetupComplete()); EXPECT_TRUE(sync()->IsFirstSetupInProgress()); - base::ListValue args; - args.AppendBoolean(false /* show advanced */); - handler()->HandleConfirm(&args); + handler()->HandleConfirm(nullptr); did_user_explicitly_interact = true; EXPECT_FALSE(sync()->IsFirstSetupInProgress()); @@ -336,9 +335,7 @@ EXPECT_FALSE(sync()->IsFirstSetupComplete()); EXPECT_TRUE(sync()->IsFirstSetupInProgress()); - base::ListValue args; - args.AppendBoolean(true /* show advanced */); - handler()->HandleConfirm(&args); + handler()->HandleGoToSettings(nullptr); did_user_explicitly_interact = true; EXPECT_FALSE(sync()->IsFirstSetupInProgress());
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc index 701a65f..e6e68e00 100644 --- a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc +++ b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
@@ -38,8 +38,8 @@ IDS_SYNC_CONFIRMATION_PERSONALIZE_SERVICES_TITLE); source->AddLocalizedString("syncConfirmationPersonalizeServicesBody", IDS_SYNC_CONFIRMATION_PERSONALIZE_SERVICES_BODY); - source->AddLocalizedString("syncConfirmationSyncSettingsLabel", - IDS_SYNC_CONFIRMATION_SYNC_SETTINGS_LABEL); + source->AddLocalizedString("syncConfirmationSyncSettingsLinkBody", + IDS_SYNC_CONFIRMATION_SYNC_SETTINGS_LINK_BODY); source->AddLocalizedString("syncDisabledConfirmationDetails", IDS_SYNC_DISABLED_CONFIRMATION_DETAILS);
diff --git a/chromeos/dbus/dbus_thread_manager.cc b/chromeos/dbus/dbus_thread_manager.cc index e25de68..88571830 100644 --- a/chromeos/dbus/dbus_thread_manager.cc +++ b/chromeos/dbus/dbus_thread_manager.cc
@@ -309,6 +309,12 @@ DBusThreadManagerSetter::~DBusThreadManagerSetter() {} +void DBusThreadManagerSetter::SetAuthPolicyClient( + std::unique_ptr<AuthPolicyClient> client) { + DBusThreadManager::Get()->clients_browser_->auth_policy_client_ = + std::move(client); +} + void DBusThreadManagerSetter::SetBiodClient( std::unique_ptr<BiodClient> client) { DBusThreadManager::Get()->clients_common_->biod_client_ = std::move(client);
diff --git a/chromeos/dbus/dbus_thread_manager.h b/chromeos/dbus/dbus_thread_manager.h index c7f793d..b16c9eeb 100644 --- a/chromeos/dbus/dbus_thread_manager.h +++ b/chromeos/dbus/dbus_thread_manager.h
@@ -180,6 +180,7 @@ public: ~DBusThreadManagerSetter(); + void SetAuthPolicyClient(std::unique_ptr<AuthPolicyClient> client); void SetBiodClient(std::unique_ptr<BiodClient> client); void SetCrasAudioClient(std::unique_ptr<CrasAudioClient> client); void SetCrosDisksClient(std::unique_ptr<CrosDisksClient> client);
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn index 2414bb9..542f5a50 100644 --- a/components/arc/BUILD.gn +++ b/components/arc/BUILD.gn
@@ -43,8 +43,6 @@ "intent_helper/link_handler_model_impl.h", "intent_helper/page_transition_util.cc", "intent_helper/page_transition_util.h", - "kiosk/arc_kiosk_bridge.cc", - "kiosk/arc_kiosk_bridge.h", "metrics/arc_metrics_service.cc", "metrics/arc_metrics_service.h", "net/arc_net_host_impl.cc", @@ -227,7 +225,6 @@ "intent_helper/intent_filter_unittest.cc", "intent_helper/link_handler_model_impl_unittest.cc", "intent_helper/page_transition_util_unittest.cc", - "kiosk/arc_kiosk_bridge_unittest.cc", ] deps = [
diff --git a/components/arc/kiosk/arc_kiosk_bridge.cc b/components/arc/kiosk/arc_kiosk_bridge.cc deleted file mode 100644 index 32ffe52..0000000 --- a/components/arc/kiosk/arc_kiosk_bridge.cc +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/arc/kiosk/arc_kiosk_bridge.h" - -#include "components/arc/arc_bridge_service.h" - -namespace arc { - -ArcKioskBridge::ArcKioskBridge(ArcBridgeService* bridge_service, - Delegate* delegate) - : ArcService(bridge_service), binding_(this), delegate_(delegate) { - DCHECK(delegate_); - arc_bridge_service()->kiosk()->AddObserver(this); -} - -ArcKioskBridge::~ArcKioskBridge() { - arc_bridge_service()->kiosk()->RemoveObserver(this); -} - -void ArcKioskBridge::OnInstanceReady() { - mojom::KioskInstance* kiosk_instance = - ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service()->kiosk(), Init); - DCHECK(kiosk_instance); - mojom::KioskHostPtr host_proxy; - binding_.Bind(mojo::MakeRequest(&host_proxy)); - kiosk_instance->Init(std::move(host_proxy)); -} - -void ArcKioskBridge::OnMaintenanceSessionCreated(int32_t session_id) { - session_id_ = session_id; - delegate_->OnMaintenanceSessionCreated(); - // TODO(poromov@) Show appropriate splash screen. -} - -void ArcKioskBridge::OnMaintenanceSessionFinished(int32_t session_id, - bool success) { - // Filter only callbacks for the started kiosk session. - if (session_id != session_id_) - return; - session_id_ = -1; - delegate_->OnMaintenanceSessionFinished(); -} - -} // namespace arc
diff --git a/components/arc/kiosk/arc_kiosk_bridge.h b/components/arc/kiosk/arc_kiosk_bridge.h deleted file mode 100644 index 2c46e05..0000000 --- a/components/arc/kiosk/arc_kiosk_bridge.h +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_ARC_KIOSK_ARC_KIOSK_BRIDGE_H_ -#define COMPONENTS_ARC_KIOSK_ARC_KIOSK_BRIDGE_H_ - -#include <map> - -#include "base/macros.h" -#include "components/arc/arc_service.h" -#include "components/arc/common/kiosk.mojom.h" -#include "components/arc/instance_holder.h" -#include "mojo/public/cpp/bindings/binding.h" - -namespace arc { - -class ArcBridgeService; - -class ArcKioskBridge : public ArcService, - public InstanceHolder<mojom::KioskInstance>::Observer, - public mojom::KioskHost { - public: - // Received IPCs are passed to this delegate. - class Delegate { - public: - virtual ~Delegate() = default; - virtual void OnMaintenanceSessionCreated() = 0; - virtual void OnMaintenanceSessionFinished() = 0; - }; - - // |delegate| should be alive while the ArcKioskBridge instance is alive. - ArcKioskBridge(ArcBridgeService* bridge_service, Delegate* delegate); - ~ArcKioskBridge() override; - - // InstanceHolder<mojom::KioskInstance>::Observer overrides. - void OnInstanceReady() override; - - // mojom::KioskHost overrides. - void OnMaintenanceSessionCreated(int32_t session_id) override; - void OnMaintenanceSessionFinished(int32_t session_id, bool success) override; - - private: - mojo::Binding<mojom::KioskHost> binding_; - Delegate* const delegate_; - - // Tracks current maintenance session id. - int32_t session_id_ = -1; - - DISALLOW_COPY_AND_ASSIGN(ArcKioskBridge); -}; - -} // namespace arc - -#endif // COMPONENTS_ARC_KIOSK_ARC_KIOSK_BRIDGE_H_
diff --git a/components/browsing_data/core/BUILD.gn b/components/browsing_data/core/BUILD.gn index c3fb039a..4f0e479 100644 --- a/components/browsing_data/core/BUILD.gn +++ b/components/browsing_data/core/BUILD.gn
@@ -23,6 +23,8 @@ "counters/passwords_counter.h", "counters/site_settings_counter.cc", "counters/site_settings_counter.h", + "counters/sync_tracker.cc", + "counters/sync_tracker.h", "history_notice_utils.cc", "history_notice_utils.h", "pref_names.cc",
diff --git a/components/browsing_data/core/counters/autofill_counter.cc b/components/browsing_data/core/counters/autofill_counter.cc index 0b9a7d8..30127cb 100644 --- a/components/browsing_data/core/counters/autofill_counter.cc +++ b/components/browsing_data/core/counters/autofill_counter.cc
@@ -31,26 +31,21 @@ scoped_refptr<autofill::AutofillWebDataService> web_data_service, syncer::SyncService* sync_service) : web_data_service_(web_data_service), - sync_service_(sync_service), + sync_tracker_(this, sync_service), suggestions_query_(0), credit_cards_query_(0), addresses_query_(0), num_suggestions_(0), num_credit_cards_(0), - num_addresses_(0), - autofill_sync_enabled_() {} + num_addresses_(0) {} AutofillCounter::~AutofillCounter() { CancelAllRequests(); - if (sync_service_) - sync_service_->RemoveObserver(this); } void AutofillCounter::OnInitialized() { DCHECK(web_data_service_); - if (sync_service_) - sync_service_->AddObserver(this); - autofill_sync_enabled_ = IsAutofillSyncEnabled(sync_service_); + sync_tracker_.OnInitialized(base::Bind(&IsAutofillSyncEnabled)); } const char* AutofillCounter::GetPrefName() const { @@ -172,7 +167,7 @@ auto reported_result = base::MakeUnique<AutofillResult>( this, num_suggestions_, num_credit_cards_, num_addresses_, - autofill_sync_enabled_); + sync_tracker_.IsSyncActive()); ReportResult(std::move(reported_result)); } @@ -185,14 +180,6 @@ web_data_service_->CancelRequest(addresses_query_); } -void AutofillCounter::OnStateChanged(syncer::SyncService* sync) { - bool sync_enabled_new = IsAutofillSyncEnabled(sync); - if (autofill_sync_enabled_ != sync_enabled_new) { - autofill_sync_enabled_ = sync_enabled_new; - Restart(); - } -} - // AutofillCounter::AutofillResult --------------------------------------------- AutofillCounter::AutofillResult::AutofillResult(const AutofillCounter* source,
diff --git a/components/browsing_data/core/counters/autofill_counter.h b/components/browsing_data/core/counters/autofill_counter.h index 7352a0c..8c657dc 100644 --- a/components/browsing_data/core/counters/autofill_counter.h +++ b/components/browsing_data/core/counters/autofill_counter.h
@@ -10,7 +10,7 @@ #include "base/time/time.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/browsing_data/core/counters/browsing_data_counter.h" -#include "components/sync/driver/sync_service_observer.h" +#include "components/browsing_data/core/counters/sync_tracker.h" #include "components/webdata/common/web_data_service_consumer.h" namespace autofill { @@ -20,8 +20,7 @@ namespace browsing_data { class AutofillCounter : public browsing_data::BrowsingDataCounter, - public WebDataServiceConsumer, - public syncer::SyncServiceObserver { + public WebDataServiceConsumer { public: class AutofillResult : public SyncResult { public: @@ -68,16 +67,13 @@ WebDataServiceBase::Handle handle, std::unique_ptr<WDTypedResult> result) override; - // SyncServiceObserver implementation. - void OnStateChanged(syncer::SyncService* sync) override; - // Cancel all pending requests to AutofillWebdataService. void CancelAllRequests(); base::ThreadChecker thread_checker_; scoped_refptr<autofill::AutofillWebDataService> web_data_service_; - syncer::SyncService* sync_service_; + SyncTracker sync_tracker_; WebDataServiceBase::Handle suggestions_query_; WebDataServiceBase::Handle credit_cards_query_; @@ -86,7 +82,6 @@ ResultInt num_suggestions_; ResultInt num_credit_cards_; ResultInt num_addresses_; - bool autofill_sync_enabled_; base::Time period_start_for_testing_;
diff --git a/components/browsing_data/core/counters/history_counter.cc b/components/browsing_data/core/counters/history_counter.cc index c75416a..376e5e8 100644 --- a/components/browsing_data/core/counters/history_counter.cc +++ b/components/browsing_data/core/counters/history_counter.cc
@@ -23,24 +23,19 @@ syncer::SyncService* sync_service) : history_service_(history_service), web_history_service_callback_(callback), - sync_service_(sync_service), + sync_tracker_(this, sync_service), has_synced_visits_(false), local_counting_finished_(false), web_counting_finished_(false), - history_sync_enabled_(false), weak_ptr_factory_(this) { DCHECK(history_service_); } -HistoryCounter::~HistoryCounter() { - if (sync_service_) - sync_service_->RemoveObserver(this); -} +HistoryCounter::~HistoryCounter() {} void HistoryCounter::OnInitialized() { - if (sync_service_) - sync_service_->AddObserver(this); - history_sync_enabled_ = !!GetWebHistoryService(); + sync_tracker_.OnInitialized(base::Bind(&HistoryCounter::IsHistorySyncEnabled, + base::Unretained(this))); } bool HistoryCounter::HasTrackedTasks() { @@ -182,18 +177,12 @@ return; ReportResult(base::MakeUnique<HistoryResult>( - this, local_result_, history_sync_enabled_, has_synced_visits_)); + this, local_result_, sync_tracker_.IsSyncActive(), has_synced_visits_)); } -void HistoryCounter::OnStateChanged(syncer::SyncService* sync) { - bool history_sync_enabled_new_state = !!GetWebHistoryService(); - - // If the history sync was just enabled or disabled, restart the counter - // so that we update the result accordingly. - if (history_sync_enabled_ != history_sync_enabled_new_state) { - history_sync_enabled_ = history_sync_enabled_new_state; - Restart(); - } +bool HistoryCounter::IsHistorySyncEnabled( + const syncer::SyncService* sync_service) { + return !!GetWebHistoryService(); } HistoryCounter::HistoryResult::HistoryResult(const HistoryCounter* source,
diff --git a/components/browsing_data/core/counters/history_counter.h b/components/browsing_data/core/counters/history_counter.h index 15cf9060..985365c 100644 --- a/components/browsing_data/core/counters/history_counter.h +++ b/components/browsing_data/core/counters/history_counter.h
@@ -10,15 +10,14 @@ #include "base/task/cancelable_task_tracker.h" #include "base/timer/timer.h" #include "components/browsing_data/core/counters/browsing_data_counter.h" +#include "components/browsing_data/core/counters/sync_tracker.h" #include "components/history/core/browser/history_service.h" #include "components/history/core/browser/web_history_service.h" #include "components/sync/driver/sync_service.h" -#include "components/sync/driver/sync_service_observer.h" namespace browsing_data { -class HistoryCounter : public browsing_data::BrowsingDataCounter, - public syncer::SyncServiceObserver { +class HistoryCounter : public browsing_data::BrowsingDataCounter { public: typedef base::Callback<history::WebHistoryService*()> GetUpdatedWebHistoryServiceCallback; @@ -60,14 +59,13 @@ history::WebHistoryService* GetWebHistoryService(); - // SyncServiceObserver implementation. - void OnStateChanged(syncer::SyncService* sync) override; + bool IsHistorySyncEnabled(const syncer::SyncService* sync_service); history::HistoryService* history_service_; GetUpdatedWebHistoryServiceCallback web_history_service_callback_; - syncer::SyncService* sync_service_; + SyncTracker sync_tracker_; bool has_synced_visits_; @@ -82,8 +80,6 @@ BrowsingDataCounter::ResultInt local_result_; - bool history_sync_enabled_; - base::WeakPtrFactory<HistoryCounter> weak_ptr_factory_; };
diff --git a/components/browsing_data/core/counters/passwords_counter.cc b/components/browsing_data/core/counters/passwords_counter.cc index b78cd06..9ee62cf 100644 --- a/components/browsing_data/core/counters/passwords_counter.cc +++ b/components/browsing_data/core/counters/passwords_counter.cc
@@ -25,21 +25,17 @@ PasswordsCounter::PasswordsCounter( scoped_refptr<password_manager::PasswordStore> store, syncer::SyncService* sync_service) - : store_(store), sync_service_(sync_service), password_sync_enabled_() { + : store_(store), sync_tracker_(this, sync_service) { DCHECK(store_); } PasswordsCounter::~PasswordsCounter() { store_->RemoveObserver(this); - if (sync_service_) - sync_service_->RemoveObserver(this); } void PasswordsCounter::OnInitialized() { + sync_tracker_.OnInitialized(base::Bind(&IsPasswordSyncEnabled)); store_->AddObserver(this); - if (sync_service_) - sync_service_->AddObserver(this); - password_sync_enabled_ = IsPasswordSyncEnabled(sync_service_); } const char* PasswordsCounter::GetPrefName() const { @@ -64,7 +60,7 @@ return form->date_created >= start; }); ReportResult(base::MakeUnique<SyncResult>(this, num_passwords, - password_sync_enabled_)); + sync_tracker_.IsSyncActive())); } void PasswordsCounter::OnLoginsChanged( @@ -72,13 +68,4 @@ Restart(); } -void PasswordsCounter::OnStateChanged(syncer::SyncService* sync) { - bool sync_enabled_new = IsPasswordSyncEnabled(sync_service_); - - if (password_sync_enabled_ != sync_enabled_new) { - password_sync_enabled_ = sync_enabled_new; - Restart(); - } -} - } // namespace browsing_data
diff --git a/components/browsing_data/core/counters/passwords_counter.h b/components/browsing_data/core/counters/passwords_counter.h index bb71ff3..bfdb086 100644 --- a/components/browsing_data/core/counters/passwords_counter.h +++ b/components/browsing_data/core/counters/passwords_counter.h
@@ -9,16 +9,15 @@ #include <vector> #include "components/browsing_data/core/counters/browsing_data_counter.h" +#include "components/browsing_data/core/counters/sync_tracker.h" #include "components/password_manager/core/browser/password_store.h" #include "components/password_manager/core/browser/password_store_consumer.h" -#include "components/sync/driver/sync_service_observer.h" namespace browsing_data { class PasswordsCounter : public browsing_data::BrowsingDataCounter, public password_manager::PasswordStoreConsumer, - public password_manager::PasswordStore::Observer, - public syncer::SyncServiceObserver { + public password_manager::PasswordStore::Observer { public: explicit PasswordsCounter( scoped_refptr<password_manager::PasswordStore> store, @@ -40,15 +39,11 @@ void OnLoginsChanged( const password_manager::PasswordStoreChangeList& changes) override; - // SyncServiceObserver implementation. - void OnStateChanged(syncer::SyncService* sync) override; - void Count() override; base::CancelableTaskTracker cancelable_task_tracker_; scoped_refptr<password_manager::PasswordStore> store_; - syncer::SyncService* sync_service_; - bool password_sync_enabled_; + SyncTracker sync_tracker_; }; } // namespace browsing_data
diff --git a/components/browsing_data/core/counters/sync_tracker.cc b/components/browsing_data/core/counters/sync_tracker.cc new file mode 100644 index 0000000..5c25a3c --- /dev/null +++ b/components/browsing_data/core/counters/sync_tracker.cc
@@ -0,0 +1,44 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/browsing_data/core/counters/sync_tracker.h" + +#include "components/browsing_data/core/counters/browsing_data_counter.h" +#include "components/sync/driver/sync_service.h" + +namespace browsing_data { + +SyncTracker::SyncTracker(BrowsingDataCounter* counter, + syncer::SyncService* sync_service) + : counter_(counter), sync_service_(sync_service), sync_enabled_() { + DCHECK(counter_); +} + +SyncTracker::~SyncTracker() { + if (sync_service_) + sync_service_->RemoveObserver(this); +} + +void SyncTracker::OnInitialized(SyncPredicate predicate) { + DCHECK(!predicate.is_null()); + predicate_ = predicate; + if (sync_service_) + sync_service_->AddObserver(this); + sync_enabled_ = predicate_.Run(sync_service_); +} + +bool SyncTracker::IsSyncActive() { + return sync_enabled_; +} + +void SyncTracker::OnStateChanged(syncer::SyncService* sync) { + bool sync_enabled_new = predicate_.Run(sync_service_); + + if (sync_enabled_ != sync_enabled_new) { + sync_enabled_ = sync_enabled_new; + counter_->Restart(); + } +} + +} // namespace browsing_data
diff --git a/components/browsing_data/core/counters/sync_tracker.h b/components/browsing_data/core/counters/sync_tracker.h new file mode 100644 index 0000000..df8ca4f --- /dev/null +++ b/components/browsing_data/core/counters/sync_tracker.h
@@ -0,0 +1,40 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_BROWSING_DATA_CORE_COUNTERS_SYNC_TRACKER_H_ +#define COMPONENTS_BROWSING_DATA_CORE_COUNTERS_SYNC_TRACKER_H_ + +#include "base/callback.h" +#include "components/sync/driver/sync_service_observer.h" + +namespace browsing_data { + +// A helper class that subscribes to sync changes and notifies +// |counter| when the sync state changes. +class BrowsingDataCounter; + +class SyncTracker : public syncer::SyncServiceObserver { + public: + using SyncPredicate = base::Callback<bool(const syncer::SyncService*)>; + + SyncTracker(BrowsingDataCounter* counter, syncer::SyncService* sync_service); + ~SyncTracker() override; + + void OnInitialized(SyncPredicate predicate); + + bool IsSyncActive(); + + private: + // SyncServiceObserver implementation. + void OnStateChanged(syncer::SyncService* sync) override; + + BrowsingDataCounter* counter_; + syncer::SyncService* sync_service_; + SyncPredicate predicate_; + bool sync_enabled_; +}; + +} // namespace browsing_data + +#endif // COMPONENTS_BROWSING_DATA_CORE_COUNTERS_SYNC_TRACKER_H_
diff --git a/components/exo/BUILD.gn b/components/exo/BUILD.gn index 57d8790..02fbac1 100644 --- a/components/exo/BUILD.gn +++ b/components/exo/BUILD.gn
@@ -10,6 +10,15 @@ sources = [ "buffer.cc", "buffer.h", + "data_device.cc", + "data_device.h", + "data_device_delegate.h", + "data_offer.cc", + "data_offer.h", + "data_offer_delegate.h", + "data_source.cc", + "data_source.h", + "data_source_delegate.h", "display.cc", "display.h", "gaming_seat.h",
diff --git a/components/exo/data_device.cc b/components/exo/data_device.cc new file mode 100644 index 0000000..2d6864f --- /dev/null +++ b/components/exo/data_device.cc
@@ -0,0 +1,31 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/exo/data_device.h" + +#include "base/logging.h" +#include "components/exo/data_device_delegate.h" + +namespace exo { + +DataDevice::DataDevice(DataDeviceDelegate* delegate) : delegate_(delegate) {} + +DataDevice::~DataDevice() { + delegate_->OnDataDeviceDestroying(this); +} + +void DataDevice::StartDrag(const DataSource* source_resource, + Surface* origin_resource, + Surface* icon_resource, + uint32_t serial) { + // TODO(hirono): Check if serial is valid. crbug.com/746111 + NOTIMPLEMENTED(); +} + +void DataDevice::SetSelection(const DataSource* source, uint32_t serial) { + // TODO(hirono): Check if serial is valid. crbug.com/746111 + NOTIMPLEMENTED(); +} + +} // namespace exo
diff --git a/components/exo/data_device.h b/components/exo/data_device.h new file mode 100644 index 0000000..f2f9696 --- /dev/null +++ b/components/exo/data_device.h
@@ -0,0 +1,50 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_EXO_DATA_DEVICE_H_ +#define COMPONENTS_EXO_DATA_DEVICE_H_ + +#include <cstdint> + +#include "base/macros.h" + +namespace exo { + +class DataDeviceDelegate; +class DataSource; +class Surface; + +enum class DndAction { kNone, kCopy, kMove, kAsk }; + +// Data transfer device providing access to inter-client data transfer +// mechanisms such as copy-and-paste and drag-and-drop. +class DataDevice { + public: + explicit DataDevice(DataDeviceDelegate* delegate); + ~DataDevice(); + + // Starts drag-and-drop operation. + // |source| is data source for the eventual transfer or null if data passing + // is handled by a client internally. |origin| is a surface where the drag + // originates. |icon| is drag-and-drop icon surface, which can be nullptr. + // |serial| is a unique number of implicit grab. + void StartDrag(const DataSource* source, + Surface* origin, + Surface* icon, + uint32_t serial); + + // Copies data to the selection. + // |source| is data source for the selection, or nullptr to unset the + // selection. |serial| is a unique number of event which tigers SetSelection. + void SetSelection(const DataSource* source, uint32_t serial); + + private: + DataDeviceDelegate* const delegate_; + + DISALLOW_COPY_AND_ASSIGN(DataDevice); +}; + +} // namespace exo + +#endif // COMPONENTS_EXO_DATA_DEVICE_H_
diff --git a/components/exo/data_device_delegate.h b/components/exo/data_device_delegate.h new file mode 100644 index 0000000..c9f2e3d --- /dev/null +++ b/components/exo/data_device_delegate.h
@@ -0,0 +1,66 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_EXO_DATA_DEVICE_DELEGATE_H_ +#define COMPONENTS_EXO_DATA_DEVICE_DELEGATE_H_ + +#include <string> +#include <vector> + +#include "base/containers/flat_set.h" + +namespace base { +class TimeTicks; +} + +namespace gfx { +class PointF; +} + +namespace exo { + +class DataDevice; +class DataOffer; +enum class DndAction; + +// Handles events on data devices in context-specific ways. +class DataDeviceDelegate { + public: + // Called at the top of the data device's destructor, to give observers a + // chance to remove themselves. + virtual void OnDataDeviceDestroying(DataDevice* data_device) = 0; + + // Called when DataOffer object is delivered from a client. DataDeviceDelegate + // has responsibility to release the returned DataOffer object. + virtual DataOffer* OnDataOffer( + const std::vector<std::string>& mime_types, + const base::flat_set<DndAction>& source_actions, + DndAction dnd_action) = 0; + + // Called during a drag operation when pointer enters |surface|. + virtual void OnEnter(Surface* surface, + const gfx::PointF& location, + const DataOffer& data_offer) = 0; + + // Called during a drag operation when pointer leaves |surface|. + virtual void OnLeave() = 0; + + // Called during a drag operation when pointer moves on the |surface|. + virtual void OnMotion(base::TimeTicks time_stamp, + const gfx::PointF& location) = 0; + + // Called during a drag operation when user drops dragging data on the + // |surface|. + virtual void OnDrop() = 0; + + // Called when the data is pasted on the DataDevice. + virtual void OnSelection(const DataOffer& data_offer) = 0; + + protected: + virtual ~DataDeviceDelegate() {} +}; + +} // namespace exo + +#endif // COMPONENTS_EXO_DATA_DEVICE_DELEGATE_H_
diff --git a/components/exo/data_offer.cc b/components/exo/data_offer.cc new file mode 100644 index 0000000..057a3062 --- /dev/null +++ b/components/exo/data_offer.cc
@@ -0,0 +1,31 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/exo/data_offer.h" + +#include "components/exo/data_offer_delegate.h" + +namespace exo { + +DataOffer::DataOffer(DataOfferDelegate* delegate) : delegate_(delegate) {} + +DataOffer::~DataOffer() { + delegate_->OnDataOfferDestroying(this); +} + +void DataOffer::Accept(const std::string& mime_type) { + NOTIMPLEMENTED(); +} +void DataOffer::Receive(const std::string& mime_type, base::ScopedFD fd) { + NOTIMPLEMENTED(); +} +void DataOffer::Finish() { + NOTIMPLEMENTED(); +} +void DataOffer::SetActions(const base::flat_set<DndAction>& dnd_actions, + DndAction preferred_action) { + NOTIMPLEMENTED(); +} + +} // namespace exo
diff --git a/components/exo/data_offer.h b/components/exo/data_offer.h new file mode 100644 index 0000000..7b1fa034 --- /dev/null +++ b/components/exo/data_offer.h
@@ -0,0 +1,49 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_EXO_DATA_OFFER_H_ +#define COMPONENTS_EXO_DATA_OFFER_H_ + +#include <cstdint> +#include <string> + +#include "base/containers/flat_set.h" +#include "base/files/scoped_file.h" +#include "base/macros.h" +#include "ui/base/class_property.h" + +namespace exo { + +class DataOfferDelegate; +enum class DndAction; + +// Object representing transferred data offered to a client. +class DataOffer : public ui::PropertyHandler { + public: + explicit DataOffer(DataOfferDelegate* delegate); + ~DataOffer(); + + // Accepts one of the offered mime types. + void Accept(const std::string& mime_type); + + // Requests that the data is transferred. |fd| is a file descriptor for data + // transfer. + void Receive(const std::string& mime_type, base::ScopedFD fd); + + // Called when the client is no longer using the data offer object. + void Finish(); + + // Sets the available/preferred drag-and-drop actions. + void SetActions(const base::flat_set<DndAction>& dnd_actions, + DndAction preferred_action); + + private: + DataOfferDelegate* const delegate_; + + DISALLOW_COPY_AND_ASSIGN(DataOffer); +}; + +} // namespace exo + +#endif // COMPONENTS_EXO_DATA_OFFER_H_
diff --git a/components/exo/data_offer_delegate.h b/components/exo/data_offer_delegate.h new file mode 100644 index 0000000..41337c3 --- /dev/null +++ b/components/exo/data_offer_delegate.h
@@ -0,0 +1,38 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_EXO_DATA_OFFER_DELEGATE_H_ +#define COMPONENTS_EXO_DATA_OFFER_DELEGATE_H_ + +#include <string> + +namespace exo { + +class DataOffer; +enum class DndAction; + +// Handles events on data devices in context-specific ways. +class DataOfferDelegate { + public: + // Called at the top of the data device's destructor, to give observers a + // chance to remove themselves. + virtual void OnDataOfferDestroying(DataOffer* offer) = 0; + + // Called when |mime_type| is offered by the client. + virtual void OnOffer(const std::string& mime_type) = 0; + + // Called when possible |source_actions| is offered by the client. + virtual void OnSourceActions( + const base::flat_set<DndAction>& source_actions) = 0; + + // Called when current |action| is offered by the client. + virtual void OnAction(DndAction action) = 0; + + protected: + virtual ~DataOfferDelegate() {} +}; + +} // namespace exo + +#endif // COMPONENTS_EXO_DATA_OFFER_DELEGATE_H_
diff --git a/components/exo/data_source.cc b/components/exo/data_source.cc new file mode 100644 index 0000000..e70ddfa --- /dev/null +++ b/components/exo/data_source.cc
@@ -0,0 +1,25 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/exo/data_source.h" + +#include "components/exo/data_source_delegate.h" + +namespace exo { + +DataSource::DataSource(DataSourceDelegate* delegate) : delegate_(delegate) {} + +DataSource::~DataSource() { + delegate_->OnDataSourceDestroying(this); +} + +void DataSource::Offer(const std::string& mime_type) { + NOTIMPLEMENTED(); +} + +void DataSource::SetActions(const base::flat_set<DndAction>& dnd_actions) { + NOTIMPLEMENTED(); +} + +} // namespace exo
diff --git a/components/exo/data_source.h b/components/exo/data_source.h new file mode 100644 index 0000000..c8a1b7a --- /dev/null +++ b/components/exo/data_source.h
@@ -0,0 +1,38 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_EXO_DATA_SOURCE_H_ +#define COMPONENTS_EXO_DATA_SOURCE_H_ + +#include <string> + +#include "base/containers/flat_set.h" +#include "base/macros.h" + +namespace exo { + +class DataSourceDelegate; +enum class DndAction; + +// Object representing transferred data offered by a client. +class DataSource { + public: + explicit DataSource(DataSourceDelegate* delegate); + ~DataSource(); + + // Adds an offered mime type. + void Offer(const std::string& mime_type); + + // Sets the available drag-and-drop actions. + void SetActions(const base::flat_set<DndAction>& dnd_actions); + + private: + DataSourceDelegate* const delegate_; + + DISALLOW_COPY_AND_ASSIGN(DataSource); +}; + +} // namespace exo + +#endif // COMPONENTS_EXO_DATA_SOURCE_H_
diff --git a/components/exo/data_source_delegate.h b/components/exo/data_source_delegate.h new file mode 100644 index 0000000..6c2c2bf --- /dev/null +++ b/components/exo/data_source_delegate.h
@@ -0,0 +1,47 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_EXO_DATA_SOURCE_DELEGATE_H_ +#define COMPONENTS_EXO_DATA_SOURCE_DELEGATE_H_ + +#include <string> + +#include "base/files/scoped_file.h" + +namespace exo { + +class DataSource; + +// Handles events on data devices in context-specific ways. +class DataSourceDelegate { + public: + // Called at the top of the data device's destructor, to give observers a + // chance to remove themselves. + virtual void OnDataSourceDestroying(DataSource* source) = 0; + + // Called when a target accepts an offered mime type. + virtual void OnTarget(const std::string& mime_type) = 0; + + // Called when the data is requested. + virtual void OnSend(const std::string& mime_type, base::ScopedFD fd) = 0; + + // Called when selection was cancelled. + virtual void OnCancelled() = 0; + + // Called when the drag-and-drop operation physically finished. + virtual void OnDndDropPerformed() = 0; + + // Called when the drag-and-drop operation concluded. + virtual void OnDndFinished() = 0; + + // Called when the action is selected by the compositor. + virtual void OnAction(DndAction dnd_action) = 0; + + protected: + virtual ~DataSourceDelegate() {} +}; + +} // namespace exo + +#endif // COMPONENTS_EXO_DATA_SOURCE_DELEGATE_H_
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc index 20880dc..3801c92 100644 --- a/components/exo/wayland/server.cc +++ b/components/exo/wayland/server.cc
@@ -48,6 +48,12 @@ #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" #include "components/exo/buffer.h" +#include "components/exo/data_device.h" +#include "components/exo/data_device_delegate.h" +#include "components/exo/data_offer.h" +#include "components/exo/data_offer_delegate.h" +#include "components/exo/data_source.h" +#include "components/exo/data_source_delegate.h" #include "components/exo/display.h" #include "components/exo/gamepad_delegate.h" #include "components/exo/gaming_seat.h" @@ -151,6 +157,55 @@ return TimeTicksToMilliseconds(base::TimeTicks::Now()); } +uint32_t WaylandDataDeviceManagerDndAction(DndAction action) { + switch (action) { + case DndAction::kNone: + return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; + case DndAction::kCopy: + return WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY; + case DndAction::kMove: + return WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE; + case DndAction::kAsk: + return WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK; + } + NOTREACHED(); +} + +uint32_t WaylandDataDeviceManagerDndActions( + const base::flat_set<DndAction>& dnd_actions) { + uint32_t actions = 0; + for (DndAction action : dnd_actions) + actions |= WaylandDataDeviceManagerDndAction(action); + return actions; +} + +DndAction DataDeviceManagerDndAction(uint32_t value) { + switch (value) { + case WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE: + return DndAction::kNone; + case WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY: + return DndAction::kCopy; + case WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE: + return DndAction::kMove; + case WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK: + return DndAction::kAsk; + default: + NOTREACHED(); + return DndAction::kNone; + } +} + +base::flat_set<DndAction> DataDeviceManagerDndActions(uint32_t value) { + base::flat_set<DndAction> actions; + if (value & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) + actions.insert(DndAction::kCopy); + if (value & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE) + actions.insert(DndAction::kMove); + if (value & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK) + actions.insert(DndAction::kAsk); + return actions; +} + // A property key containing the surface resource that is associated with // window. If unset, no surface resource is associated with window. DEFINE_UI_CLASS_PROPERTY_KEY(wl_resource*, kSurfaceResourceKey, nullptr); @@ -176,10 +231,18 @@ // object is associated with a window. DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasStylusToolKey, false); +// A property key containing the data offer resource that is associated with +// data offer object. +DEFINE_UI_CLASS_PROPERTY_KEY(wl_resource*, kDataOfferResourceKey, nullptr); + wl_resource* GetSurfaceResource(Surface* surface) { return surface->GetProperty(kSurfaceResourceKey); } +wl_resource* GetDataOfferResource(const DataOffer* data_offer) { + return data_offer->GetProperty(kDataOfferResourceKey); +} + //////////////////////////////////////////////////////////////////////////////// // wl_buffer_interface: @@ -2639,26 +2702,206 @@ } //////////////////////////////////////////////////////////////////////////////// +// wl_data_source_interface: + +class WaylandDataSourceDelegate : public DataSourceDelegate { + public: + explicit WaylandDataSourceDelegate(wl_resource* source) + : data_source_resource_(source) {} + + // Overridden from DataSourceDelegate: + void OnDataSourceDestroying(DataSource* device) override { delete this; } + void OnTarget(const std::string& mime_type) override { + wl_data_source_send_target(data_source_resource_, mime_type.c_str()); + } + void OnSend(const std::string& mime_type, base::ScopedFD fd) override { + wl_data_source_send_send(data_source_resource_, mime_type.c_str(), + fd.get()); + } + void OnCancelled() override { + wl_data_source_send_cancelled(data_source_resource_); + } + void OnDndDropPerformed() override { + wl_data_source_send_dnd_drop_performed(data_source_resource_); + } + void OnDndFinished() override { + wl_data_source_send_dnd_finished(data_source_resource_); + } + void OnAction(DndAction dnd_action) override { + wl_data_source_send_action(data_source_resource_, + WaylandDataDeviceManagerDndAction(dnd_action)); + } + + private: + wl_resource* const data_source_resource_; + + DISALLOW_COPY_AND_ASSIGN(WaylandDataSourceDelegate); +}; + +void data_source_offer(wl_client* client, + wl_resource* resource, + const char* mime_type) { + GetUserDataAs<DataSource>(resource)->Offer(mime_type); +} + +void data_source_destroy(wl_client* client, wl_resource* resource) { + wl_resource_destroy(resource); +} + +void data_source_set_actions(wl_client* client, + wl_resource* resource, + uint32_t dnd_actions) { + GetUserDataAs<DataSource>(resource)->SetActions( + DataDeviceManagerDndActions(dnd_actions)); +} + +const struct wl_data_source_interface data_source_implementation = { + data_source_offer, data_source_destroy, data_source_set_actions}; + +//////////////////////////////////////////////////////////////////////////////// +// wl_data_offer_interface: + +class WaylandDataOfferDelegate : public DataOfferDelegate { + public: + explicit WaylandDataOfferDelegate(wl_resource* offer) + : data_offer_resource_(offer) {} + + // Overridden from DataOfferDelegate: + void OnDataOfferDestroying(DataOffer* device) override { delete this; } + void OnOffer(const std::string& mime_type) override { + wl_data_offer_send_offer(data_offer_resource_, mime_type.c_str()); + } + void OnSourceActions( + const base::flat_set<DndAction>& source_actions) override { + wl_data_offer_send_source_actions( + data_offer_resource_, + WaylandDataDeviceManagerDndActions(source_actions)); + } + void OnAction(DndAction action) override { + wl_data_offer_send_action(data_offer_resource_, + WaylandDataDeviceManagerDndAction(action)); + } + + private: + wl_resource* const data_offer_resource_; + + DISALLOW_COPY_AND_ASSIGN(WaylandDataOfferDelegate); +}; + +void data_offer_accept(wl_client* client, + wl_resource* resource, + uint32_t serial, + const char* mime_type) { + GetUserDataAs<DataOffer>(resource)->Accept(mime_type); +} + +void data_offer_receive(wl_client* client, + wl_resource* resource, + const char* mime_type, + int fd) { + GetUserDataAs<DataOffer>(resource)->Receive(mime_type, base::ScopedFD(fd)); +} + +void data_offer_destroy(wl_client* client, wl_resource* resource) { + wl_resource_destroy(resource); +} + +void data_offer_finish(wl_client* client, wl_resource* resource) { + GetUserDataAs<DataOffer>(resource)->Finish(); +} + +void data_offer_set_actions(wl_client* client, + wl_resource* resource, + uint32_t dnd_actions, + uint32_t preferred_action) { + GetUserDataAs<DataOffer>(resource)->SetActions( + DataDeviceManagerDndActions(dnd_actions), + DataDeviceManagerDndAction(preferred_action)); +} + +const struct wl_data_offer_interface data_offer_implementation = { + data_offer_accept, data_offer_receive, data_offer_finish, + data_offer_destroy, data_offer_set_actions}; + +//////////////////////////////////////////////////////////////////////////////// // wl_data_device_interface: +class WaylandDataDeviceDelegate : public DataDeviceDelegate { + public: + WaylandDataDeviceDelegate(wl_client* client, wl_resource* device_resource) + : client_(client), data_device_resource_(device_resource) {} + + // Overridden from DataDeviceDelegate: + void OnDataDeviceDestroying(DataDevice* device) override { delete this; } + class DataOffer* OnDataOffer(const std::vector<std::string>& mime_types, + const base::flat_set<DndAction>& source_actions, + DndAction dnd_action) override { + wl_resource* data_offer_resource = + wl_resource_create(client_, &wl_data_offer_interface, 1, 0); + std::unique_ptr<DataOffer> data_offer = base::MakeUnique<DataOffer>( + new WaylandDataOfferDelegate(data_offer_resource)); + data_offer->SetProperty(kDataOfferResourceKey, data_offer_resource); + SetImplementation(data_offer_resource, &data_offer_implementation, + std::move(data_offer)); + + wl_data_device_send_data_offer(data_device_resource_, data_offer_resource); + + return GetUserDataAs<DataOffer>(data_offer_resource); + } + void OnEnter(Surface* surface, + const gfx::PointF& point, + const DataOffer& data_offer) override { + wl_data_device_send_enter( + data_device_resource_, + wl_display_next_serial(wl_client_get_display(client_)), + GetSurfaceResource(surface), wl_fixed_from_double(point.x()), + wl_fixed_from_double(point.y()), GetDataOfferResource(&data_offer)); + } + void OnLeave() override { wl_data_device_send_leave(data_device_resource_); } + void OnMotion(base::TimeTicks time_stamp, const gfx::PointF& point) override { + wl_data_device_send_motion( + data_device_resource_, TimeTicksToMilliseconds(time_stamp), + wl_fixed_from_double(point.x()), wl_fixed_from_double(point.y())); + } + void OnDrop() override { wl_data_device_send_drop(data_device_resource_); } + void OnSelection(const class DataOffer& data_offer) override { + wl_data_device_send_selection(data_device_resource_, + GetDataOfferResource(&data_offer)); + } + + private: + wl_client* const client_; + wl_resource* const data_device_resource_; + + DISALLOW_COPY_AND_ASSIGN(WaylandDataDeviceDelegate); +}; + void data_device_start_drag(wl_client* client, wl_resource* resource, wl_resource* source_resource, wl_resource* origin_resource, wl_resource* icon_resource, uint32_t serial) { - NOTIMPLEMENTED(); + GetUserDataAs<DataDevice>(resource)->StartDrag( + source_resource ? GetUserDataAs<DataSource>(source_resource) : nullptr, + GetUserDataAs<Surface>(origin_resource), + icon_resource ? GetUserDataAs<Surface>(icon_resource) : nullptr, serial); } void data_device_set_selection(wl_client* client, wl_resource* resource, wl_resource* data_source, uint32_t serial) { - NOTIMPLEMENTED(); + GetUserDataAs<DataDevice>(resource)->SetSelection( + GetUserDataAs<DataSource>(data_source), serial); +} + +void data_device_release(wl_client* client, wl_resource* resource) { + wl_resource_destroy(resource); } const struct wl_data_device_interface data_device_implementation = { - data_device_start_drag, data_device_set_selection}; + data_device_start_drag, data_device_set_selection, data_device_release}; //////////////////////////////////////////////////////////////////////////////// // wl_data_device_manager_interface: @@ -2666,7 +2909,11 @@ void data_device_manager_create_data_source(wl_client* client, wl_resource* resource, uint32_t id) { - NOTIMPLEMENTED(); + wl_resource* data_source_resource = + wl_resource_create(client, &wl_data_device_interface, 1, id); + SetImplementation(data_source_resource, &data_source_implementation, + base::MakeUnique<DataSource>( + new WaylandDataSourceDelegate(data_source_resource))); } void data_device_manager_get_data_device(wl_client* client, @@ -2675,9 +2922,9 @@ wl_resource* seat_resource) { wl_resource* data_device_resource = wl_resource_create(client, &wl_data_device_interface, 1, id); - - wl_resource_set_implementation(data_device_resource, - &data_device_implementation, nullptr, nullptr); + SetImplementation(data_device_resource, &data_device_implementation, + base::MakeUnique<DataDevice>(new WaylandDataDeviceDelegate( + client, data_device_resource))); } const struct wl_data_device_manager_interface @@ -2691,9 +2938,8 @@ uint32_t id) { wl_resource* resource = wl_resource_create(client, &wl_data_device_manager_interface, 1, id); - wl_resource_set_implementation(resource, &data_device_manager_implementation, - data, nullptr); + nullptr, nullptr); } ////////////////////////////////////////////////////////////////////////////////
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn index 319d951..2775981 100644 --- a/components/metrics/BUILD.gn +++ b/components/metrics/BUILD.gn
@@ -31,8 +31,6 @@ "environment_recorder.h", "execution_phase.cc", "execution_phase.h", - "field_trials_provider.cc", - "field_trials_provider.h", "file_metrics_provider.cc", "file_metrics_provider.h", "histogram_encoder.cc", @@ -348,7 +346,6 @@ "data_use_tracker_unittest.cc", "drive_metrics_provider_unittest.cc", "environment_recorder_unittest.cc", - "field_trials_provider_unittest.cc", "file_metrics_provider_unittest.cc", "histogram_encoder_unittest.cc", "machine_id_provider_win_unittest.cc",
diff --git a/components/metrics/field_trials_provider.cc b/components/metrics/field_trials_provider.cc deleted file mode 100644 index f67fc3c..0000000 --- a/components/metrics/field_trials_provider.cc +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/metrics/field_trials_provider.h" - -#include "components/metrics/proto/system_profile.pb.h" -#include "components/variations/active_field_trials.h" -#include "components/variations/synthetic_trial_registry.h" - -namespace variations { - -namespace { - -void WriteFieldTrials(const std::vector<ActiveGroupId>& field_trial_ids, - metrics::SystemProfileProto* system_profile) { - for (const ActiveGroupId& id : field_trial_ids) { - metrics::SystemProfileProto::FieldTrial* field_trial = - system_profile->add_field_trial(); - field_trial->set_name_id(id.name); - field_trial->set_group_id(id.group); - } -} - -} // namespace - -FieldTrialsProvider::FieldTrialsProvider(SyntheticTrialRegistry* registry) - : registry_(registry) {} -FieldTrialsProvider::~FieldTrialsProvider() = default; - -void FieldTrialsProvider::GetFieldTrialIds( - std::vector<ActiveGroupId>* field_trial_ids) const { - variations::GetFieldTrialActiveGroupIds(field_trial_ids); -} - -void FieldTrialsProvider::OnDidCreateMetricsLog() { - creation_times_.push_back(base::TimeTicks::Now()); -} - -void FieldTrialsProvider::ProvideSystemProfileMetrics( - metrics::SystemProfileProto* system_profile_proto) { - base::TimeTicks creation_time; - // Should always be true, but don't crash even if there is a bug. - if (!creation_times_.empty()) { - creation_time = creation_times_.back(); - creation_times_.pop_back(); - } - std::vector<ActiveGroupId> synthetic_trials; - registry_->GetSyntheticFieldTrialsOlderThan(creation_time, &synthetic_trials); - - std::vector<ActiveGroupId> field_trial_ids; - GetFieldTrialIds(&field_trial_ids); - WriteFieldTrials(field_trial_ids, system_profile_proto); - WriteFieldTrials(synthetic_trials, system_profile_proto); -} - -} // namespace variations
diff --git a/components/metrics/field_trials_provider.h b/components/metrics/field_trials_provider.h deleted file mode 100644 index 6242a20d..0000000 --- a/components/metrics/field_trials_provider.h +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_METRICS_FIELD_TRIALS_PROVIDER_H_ -#define COMPONENTS_METRICS_FIELD_TRIALS_PROVIDER_H_ - -#include <vector> - -#include "base/time/time.h" -#include "components/metrics/metrics_provider.h" - -// TODO(crbug/507665): Once MetricsProvider/SystemProfileProto are moved into -// //services/metrics, then //components/variations can depend on them, and -// this should be moved there. -namespace variations { - -class SyntheticTrialRegistry; -struct ActiveGroupId; - -class FieldTrialsProvider : public metrics::MetricsProvider { - public: - // |registry| must outlive this metrics provider. - FieldTrialsProvider(SyntheticTrialRegistry* registry); - ~FieldTrialsProvider() override; - - // metrics::MetricsProvider: - void OnDidCreateMetricsLog() override; - void ProvideSystemProfileMetrics( - metrics::SystemProfileProto* system_profile_proto) override; - - private: - // Overrideable for testing. - virtual void GetFieldTrialIds( - std::vector<ActiveGroupId>* field_trial_ids) const; - - SyntheticTrialRegistry* registry_; - - // A stack of log creation times. - // While the initial metrics log exists, there will be two logs open. - // Use a stack so that we use the right creation time for the first ongoing - // log. - // TODO(crbug/746098): Simplify InitialMetricsLog logic so this is not - // necessary. - std::vector<base::TimeTicks> creation_times_; -}; - -} // namespace variations - -#endif // COMPONENTS_METRICS_FIELD_TRIALS_PROVIDER_H_
diff --git a/components/metrics/field_trials_provider_unittest.cc b/components/metrics/field_trials_provider_unittest.cc deleted file mode 100644 index f50f63e..0000000 --- a/components/metrics/field_trials_provider_unittest.cc +++ /dev/null
@@ -1,89 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/metrics/field_trials_provider.h" - -#include "components/metrics/proto/system_profile.pb.h" -#include "components/variations/active_field_trials.h" -#include "components/variations/synthetic_trial_registry.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace variations { - -namespace { - -const ActiveGroupId kFieldTrialIds[] = {{37, 43}, {13, 47}, {23, 17}}; -const ActiveGroupId kSyntheticTrials[] = {{55, 15}, {66, 16}}; - -class TestProvider : public FieldTrialsProvider { - public: - TestProvider(SyntheticTrialRegistry* registry) - : FieldTrialsProvider(registry) {} - ~TestProvider() override {} - - void GetFieldTrialIds( - std::vector<ActiveGroupId>* field_trial_ids) const override { - ASSERT_TRUE(field_trial_ids->empty()); - for (const ActiveGroupId& id : kFieldTrialIds) { - field_trial_ids->push_back(id); - } - } -}; - -// Check that the values in |system_values| correspond to the test data -// defined at the top of this file. -void CheckSystemProfile(const metrics::SystemProfileProto& system_profile) { - ASSERT_EQ(arraysize(kFieldTrialIds) + arraysize(kSyntheticTrials), - static_cast<size_t>(system_profile.field_trial_size())); - for (size_t i = 0; i < arraysize(kFieldTrialIds); ++i) { - const metrics::SystemProfileProto::FieldTrial& field_trial = - system_profile.field_trial(i); - EXPECT_EQ(kFieldTrialIds[i].name, field_trial.name_id()); - EXPECT_EQ(kFieldTrialIds[i].group, field_trial.group_id()); - } - // Verify the right data is present for the synthetic trials. - for (size_t i = 0; i < arraysize(kSyntheticTrials); ++i) { - const metrics::SystemProfileProto::FieldTrial& field_trial = - system_profile.field_trial(i + arraysize(kFieldTrialIds)); - EXPECT_EQ(kSyntheticTrials[i].name, field_trial.name_id()); - EXPECT_EQ(kSyntheticTrials[i].group, field_trial.group_id()); - } -} - -} // namespace - -class FieldTrialsProviderTest : public ::testing::Test { - public: - FieldTrialsProviderTest() {} - ~FieldTrialsProviderTest() override {} - - protected: - // Register trials which should get recorded. - void RegisterExpectedSyntheticTrials() { - for (const ActiveGroupId& id : kSyntheticTrials) { - registry_.RegisterSyntheticFieldTrial( - SyntheticTrialGroup(id.name, id.group)); - } - } - // Register trial which shouldn't get recorded. - void RegisterExtraSyntheticTrial() { - registry_.RegisterSyntheticFieldTrial(SyntheticTrialGroup(100, 1000)); - } - - SyntheticTrialRegistry registry_; -}; - -TEST_F(FieldTrialsProviderTest, ProvideSyntheticTrials) { - TestProvider provider(®istry_); - - RegisterExpectedSyntheticTrials(); - provider.OnDidCreateMetricsLog(); - RegisterExtraSyntheticTrial(); - - metrics::SystemProfileProto proto; - provider.ProvideSystemProfileMetrics(&proto); - CheckSystemProfile(proto); -} - -} // namespace variations
diff --git a/components/metrics/metrics_log.cc b/components/metrics/metrics_log.cc index 29a5e12d..ba570a7 100644 --- a/components/metrics/metrics_log.cc +++ b/components/metrics/metrics_log.cc
@@ -31,6 +31,7 @@ #include "components/metrics/proto/user_action_event.pb.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" +#include "components/variations/active_field_trials.h" #if defined(OS_ANDROID) #include "base/android/build_info.h" @@ -41,6 +42,7 @@ #endif using base::SampleCountIterator; +typedef variations::ActiveGroupId ActiveGroupId; namespace metrics { @@ -79,6 +81,17 @@ return id.size() < 16; } +void WriteFieldTrials(const std::vector<ActiveGroupId>& field_trial_ids, + SystemProfileProto* system_profile) { + for (std::vector<ActiveGroupId>::const_iterator it = + field_trial_ids.begin(); it != field_trial_ids.end(); ++it) { + SystemProfileProto::FieldTrial* field_trial = + system_profile->add_field_trial(); + field_trial->set_name_id(it->name); + field_trial->set_group_id(it->group); + } +} + // Round a timestamp measured in seconds since epoch to one with a granularity // of an hour. This can be used before uploaded potentially sensitive // timestamps. @@ -233,6 +246,11 @@ metrics_providers[i]->ProvideGeneralMetrics(uma_proto()); } +void MetricsLog::GetFieldTrialIds( + std::vector<ActiveGroupId>* field_trial_ids) const { + variations::GetFieldTrialActiveGroupIds(field_trial_ids); +} + bool MetricsLog::HasEnvironment() const { return uma_proto()->system_profile().has_uma_enabled_date(); } @@ -285,6 +303,7 @@ std::string MetricsLog::RecordEnvironment( const std::vector<std::unique_ptr<MetricsProvider>>& metrics_providers, + const std::vector<variations::ActiveGroupId>& synthetic_trials, int64_t install_date, int64_t metrics_reporting_enabled_date) { DCHECK(!HasEnvironment()); @@ -312,6 +331,11 @@ cpu->set_signature(cpu_info.signature()); cpu->set_num_cores(base::SysInfo::NumberOfProcessors()); + std::vector<ActiveGroupId> field_trial_ids; + GetFieldTrialIds(&field_trial_ids); + WriteFieldTrials(field_trial_ids, system_profile); + WriteFieldTrials(synthetic_trials, system_profile); + for (size_t i = 0; i < metrics_providers.size(); ++i) metrics_providers[i]->ProvideSystemProfileMetrics(system_profile);
diff --git a/components/metrics/metrics_log.h b/components/metrics/metrics_log.h index 27e9033..688a624 100644 --- a/components/metrics/metrics_log.h +++ b/components/metrics/metrics_log.h
@@ -25,6 +25,10 @@ class HistogramSamples; } +namespace variations { +struct ActiveGroupId; +} + namespace metrics { namespace internal { @@ -98,6 +102,7 @@ // current environment is returned serialized as a string. std::string RecordEnvironment( const std::vector<std::unique_ptr<MetricsProvider>>& metrics_providers, + const std::vector<variations::ActiveGroupId>& synthetic_trials, int64_t install_date, int64_t metrics_reporting_enabled_date); @@ -151,6 +156,11 @@ protected: // Exposed for the sake of mocking/accessing in test code. + // Fills |field_trial_ids| with the list of initialized field trials name and + // group ids. + virtual void GetFieldTrialIds( + std::vector<variations::ActiveGroupId>* field_trial_ids) const; + ChromeUserMetricsExtension* uma_proto() { return &uma_proto_; } // Exposed to allow subclass to access to export the uma_proto. Can be used
diff --git a/components/metrics/metrics_log_unittest.cc b/components/metrics/metrics_log_unittest.cc index cb48cc09..8a1c6bc 100644 --- a/components/metrics/metrics_log_unittest.cc +++ b/components/metrics/metrics_log_unittest.cc
@@ -46,6 +46,15 @@ const int64_t kEnabledDate = 1373001211; const int64_t kEnabledDateExpected = 1373000400; // Computed from kEnabledDate. const int kSessionId = 127; +const variations::ActiveGroupId kFieldTrialIds[] = { + {37, 43}, + {13, 47}, + {23, 17} +}; +const variations::ActiveGroupId kSyntheticTrials[] = { + {55, 15}, + {66, 16} +}; class TestMetricsLog : public MetricsLog { public: @@ -79,6 +88,15 @@ base::Int64ToString(kEnabledDate)); } + void GetFieldTrialIds( + std::vector<variations::ActiveGroupId>* field_trial_ids) const override { + ASSERT_TRUE(field_trial_ids->empty()); + + for (size_t i = 0; i < arraysize(kFieldTrialIds); ++i) { + field_trial_ids->push_back(kFieldTrialIds[i]); + } + } + // Weak pointer to the PrefsService used by this log. TestingPrefServiceSimple* prefs_; @@ -103,6 +121,22 @@ EXPECT_EQ(kInstallDateExpected, system_profile.install_date()); EXPECT_EQ(kEnabledDateExpected, system_profile.uma_enabled_date()); + ASSERT_EQ(arraysize(kFieldTrialIds) + arraysize(kSyntheticTrials), + static_cast<size_t>(system_profile.field_trial_size())); + for (size_t i = 0; i < arraysize(kFieldTrialIds); ++i) { + const SystemProfileProto::FieldTrial& field_trial = + system_profile.field_trial(i); + EXPECT_EQ(kFieldTrialIds[i].name, field_trial.name_id()); + EXPECT_EQ(kFieldTrialIds[i].group, field_trial.group_id()); + } + // Verify the right data is present for the synthetic trials. + for (size_t i = 0; i < arraysize(kSyntheticTrials); ++i) { + const SystemProfileProto::FieldTrial& field_trial = + system_profile.field_trial(i + arraysize(kFieldTrialIds)); + EXPECT_EQ(kSyntheticTrials[i].name, field_trial.name_id()); + EXPECT_EQ(kSyntheticTrials[i].group, field_trial.group_id()); + } + EXPECT_EQ(TestMetricsServiceClient::kBrandForTesting, system_profile.brand_code()); @@ -255,8 +289,13 @@ TestMetricsLog log( kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); + std::vector<variations::ActiveGroupId> synthetic_trials; + // Add two synthetic trials. + synthetic_trials.push_back(kSyntheticTrials[0]); + synthetic_trials.push_back(kSyntheticTrials[1]); + log.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), - kInstallDate, kEnabledDate); + synthetic_trials, kInstallDate, kEnabledDate); // Check that the system profile on the log has the correct values set. CheckSystemProfile(log.system_profile()); @@ -272,15 +311,17 @@ TestMetricsLog log_unknown(kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); + std::vector<variations::ActiveGroupId> synthetic_trials; + log_unknown.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), - kInstallDate, kEnabledDate); + synthetic_trials, kInstallDate, kEnabledDate); EXPECT_FALSE(log_unknown.system_profile().has_uma_default_state()); client.set_enable_default(EnableMetricsDefault::OPT_IN); TestMetricsLog log_opt_in(kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); log_opt_in.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), - kInstallDate, kEnabledDate); + synthetic_trials, kInstallDate, kEnabledDate); EXPECT_TRUE(log_opt_in.system_profile().has_uma_default_state()); EXPECT_EQ(SystemProfileProto_UmaDefaultState_OPT_IN, log_opt_in.system_profile().uma_default_state()); @@ -289,7 +330,7 @@ TestMetricsLog log_opt_out(kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); log_opt_out.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), - kInstallDate, kEnabledDate); + synthetic_trials, kInstallDate, kEnabledDate); EXPECT_TRUE(log_opt_out.system_profile().has_uma_default_state()); EXPECT_EQ(SystemProfileProto_UmaDefaultState_OPT_OUT, log_opt_out.system_profile().uma_default_state()); @@ -298,7 +339,7 @@ TestMetricsLog log_managed(kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); log_managed.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), - kInstallDate, kEnabledDate); + synthetic_trials, kInstallDate, kEnabledDate); EXPECT_TRUE(log_managed.system_profile().has_uma_default_state()); EXPECT_EQ(SystemProfileProto_UmaDefaultState_POLICY_FORCED_ENABLED, log_managed.system_profile().uma_default_state()); @@ -314,7 +355,9 @@ TestMetricsProvider* test_provider = new TestMetricsProvider(); std::vector<std::unique_ptr<MetricsProvider>> metrics_providers; metrics_providers.push_back(base::WrapUnique<MetricsProvider>(test_provider)); - log.RecordEnvironment(metrics_providers, kInstallDate, kEnabledDate); + log.RecordEnvironment(metrics_providers, + std::vector<variations::ActiveGroupId>(), kInstallDate, + kEnabledDate); log.RecordStabilityMetrics(metrics_providers, base::TimeDelta(), base::TimeDelta()); @@ -331,7 +374,9 @@ TestMetricsProvider* test_provider = new TestMetricsProvider(); std::vector<std::unique_ptr<MetricsProvider>> metrics_providers; metrics_providers.push_back(base::WrapUnique<MetricsProvider>(test_provider)); - log.RecordEnvironment(metrics_providers, kInstallDate, kEnabledDate); + log.RecordEnvironment(metrics_providers, + std::vector<variations::ActiveGroupId>(), kInstallDate, + kEnabledDate); log.RecordStabilityMetrics(metrics_providers, base::TimeDelta(), base::TimeDelta());
diff --git a/components/metrics/metrics_service.cc b/components/metrics/metrics_service.cc index ef1d389..4e9fa9e 100644 --- a/components/metrics/metrics_service.cc +++ b/components/metrics/metrics_service.cc
@@ -145,7 +145,6 @@ #include "base/tracked_objects.h" #include "build/build_config.h" #include "components/metrics/environment_recorder.h" -#include "components/metrics/field_trials_provider.h" #include "components/metrics/metrics_log.h" #include "components/metrics/metrics_log_manager.h" #include "components/metrics/metrics_log_uploader.h" @@ -232,11 +231,8 @@ if (install_date == 0) local_state_->SetInt64(prefs::kInstallDate, base::Time::Now().ToTimeT()); - RegisterMetricsProvider( - base::MakeUnique<StabilityMetricsProvider>(local_state_)); - - RegisterMetricsProvider(base::MakeUnique<variations::FieldTrialsProvider>( - &synthetic_trial_registry_)); + RegisterMetricsProvider(std::unique_ptr<metrics::MetricsProvider>( + new StabilityMetricsProvider(local_state_))); } MetricsService::~MetricsService() { @@ -867,8 +863,12 @@ void MetricsService::RecordCurrentEnvironment(MetricsLog* log) { DCHECK(client_); + std::vector<variations::ActiveGroupId> synthetic_trials; + synthetic_trial_registry_.GetSyntheticFieldTrialsOlderThan( + log->creation_time(), &synthetic_trials); std::string serialized_environment = log->RecordEnvironment( - metrics_providers_, GetInstallDate(), GetMetricsReportingEnabledDate()); + metrics_providers_, synthetic_trials, GetInstallDate(), + GetMetricsReportingEnabledDate()); client_->OnEnvironmentUpdate(&serialized_environment); }
diff --git a/components/metrics/metrics_service_unittest.cc b/components/metrics/metrics_service_unittest.cc index 6c1497326..790c81b7 100644 --- a/components/metrics/metrics_service_unittest.cc +++ b/components/metrics/metrics_service_unittest.cc
@@ -191,7 +191,8 @@ // saved from a previous session. TestMetricsServiceClient client; TestMetricsLog log("client", 1, &client, GetLocalState()); - log.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), 0, 0); + log.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), + std::vector<variations::ActiveGroupId>(), 0, 0); // Record stability build time and version from previous session, so that // stability metrics (including exited cleanly flag) won't be cleared. @@ -261,7 +262,8 @@ // saved from a previous session. TestMetricsServiceClient client; TestMetricsLog log("client", 1, &client, GetLocalState()); - log.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), 0, 0); + log.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), + std::vector<variations::ActiveGroupId>(), 0, 0); // Record stability build time and version from previous session, so that // stability metrics (including exited cleanly flag) won't be cleared.
diff --git a/components/variations/synthetic_trial_registry.h b/components/variations/synthetic_trial_registry.h index db37ade0..b15fff8 100644 --- a/components/variations/synthetic_trial_registry.h +++ b/components/variations/synthetic_trial_registry.h
@@ -12,13 +12,12 @@ namespace metrics { class MetricsServiceAccessor; +class MetricsService; } // namespace metrics namespace variations { struct ActiveGroupId; -class FieldTrialsProvider; -class FieldTrialsProviderTest; class SyntheticTrialRegistry { public: @@ -33,8 +32,7 @@ private: friend metrics::MetricsServiceAccessor; - friend FieldTrialsProvider; - friend FieldTrialsProviderTest; + friend metrics::MetricsService; FRIEND_TEST_ALL_PREFIXES(SyntheticTrialRegistryTest, RegisterSyntheticTrial); FRIEND_TEST_ALL_PREFIXES(SyntheticTrialRegistryTest, RegisterSyntheticMultiGroupFieldTrial);
diff --git a/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc b/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc index 717527d3..3aae2ad7 100644 --- a/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc +++ b/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc
@@ -12,6 +12,7 @@ #include "base/scoped_observer.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" #include "components/network_session_configurator/common/network_switches.h" #include "content/browser/browsing_data/browsing_data_filter_builder_impl.h" #include "content/browser/service_worker/service_worker_context_core_observer.h" @@ -408,7 +409,15 @@ // Tests that the header is recognized on the beginning, in the middle, and on // the end of a navigation redirect chain. Each of the three parts of the chain // may or may not send the header, so there are 8 configurations to test. -IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, RedirectNavigation) { + +// Crashes on Win only. https://crbug.com/741189 +#if defined(OS_WIN) +#define MAYBE_RedirectNavigation DISABLED_RedirectNavigation +#else +#define MAYBE_RedirectNavigation RedirectNavigation +#endif +IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, + MAYBE_RedirectNavigation) { GURL page_urls[3] = { https_server()->GetURL("origin1.com", "/"), https_server()->GetURL("origin2.com", "/foo/bar"), @@ -447,7 +456,15 @@ // Tests that the header is recognized on the beginning, in the middle, and on // the end of a resource load redirect chain. Each of the three parts of the // chain may or may not send the header, so there are 8 configurations to test. -IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, RedirectResourceLoad) { + +// Crashes on Win only. https://crbug.com/741189 +#if defined(OS_WIN) +#define MAYBE_RedirectResourceLoad DISABLED_RedirectResourceLoad +#else +#define MAYBE_RedirectResourceLoad RedirectResourceLoad +#endif +IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, + MAYBE_RedirectResourceLoad) { GURL resource_urls[3] = { https_server()->GetURL("origin1.com", "/redirect-start"), https_server()->GetURL("origin2.com", "/redirect-middle"), @@ -619,7 +636,14 @@ // Tests that Clear-Site-Data is only executed on a resource fetch // if credentials are allowed in that fetch. -IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, Credentials) { + +// Crashes on Win only. https://crbug.com/741189 +#if defined(OS_WIN) +#define MAYBE_Credentials DISABLED_Credentials +#else +#define MAYBE_Credentials Credentials +#endif +IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, MAYBE_Credentials) { GURL page_template = https_server()->GetURL("origin1.com", "/"); GURL same_origin_resource = https_server()->GetURL("origin1.com", "/resource");
diff --git a/content/browser/resources/media/media_internals.html b/content/browser/resources/media/media_internals.html index fc16569..24801d8 100644 --- a/content/browser/resources/media/media_internals.html +++ b/content/browser/resources/media/media_internals.html
@@ -7,6 +7,7 @@ <html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Media Internals</title> <link rel="stylesheet" href="media_internals.css"> <script src="chrome://resources/js/cr.js"></script>
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 178d504..b7fadcf8 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -774,7 +774,14 @@ // Ensure that navigating subframes in --site-per-process mode works and the // correct documents are committed. -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteIframe) { + +// Crashes on Win only. https://crbug.com/746055 +#if defined(OS_WIN) +#define MAYBE_CrossSiteIframe DISABLED_CrossSiteIframe +#else +#define MAYBE_CrossSiteIframe CrossSiteIframe +#endif +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, MAYBE_CrossSiteIframe) { GURL main_url(embedded_test_server()->GetURL( "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))")); EXPECT_TRUE(NavigateToURL(shell(), main_url)); @@ -1885,7 +1892,15 @@ } // Ensure that OOPIFs are deleted after navigating to a new main frame. -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CleanupCrossSiteIframe) { + +// Crashes on Win only. https://crbug.com/746055 +#if defined(OS_WIN) +#define MAYBE_CleanupCrossSiteIframe DISABLED_CleanupCrossSiteIframe +#else +#define MAYBE_CleanupCrossSiteIframe CleanupCrossSiteIframe +#endif +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + MAYBE_CleanupCrossSiteIframe) { GURL main_url(embedded_test_server()->GetURL( "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))")); EXPECT_TRUE(NavigateToURL(shell(), main_url)); @@ -1942,7 +1957,14 @@ } // Ensure that root frames cannot be detached. -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, RestrictFrameDetach) { + +// Crashes on Win only. https://crbug.com/746055 +#if defined(OS_WIN) +#define MAYBE_RestrictFrameDetach DISABLED_RestrictFrameDetach +#else +#define MAYBE_RestrictFrameDetach RestrictFrameDetach +#endif +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, MAYBE_RestrictFrameDetach) { GURL main_url(embedded_test_server()->GetURL( "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))")); EXPECT_TRUE(NavigateToURL(shell(), main_url)); @@ -2004,7 +2026,13 @@ DepictFrameTree(root)); } -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, NavigateRemoteFrame) { +// Crashes on Win only. https://crbug.com/746055 +#if defined(OS_WIN) +#define MAYBE_NavigateRemoteFrame DISABLED_NavigateRemoteFrame +#else +#define MAYBE_NavigateRemoteFrame NavigateRemoteFrame +#endif +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, MAYBE_NavigateRemoteFrame) { GURL main_url(embedded_test_server()->GetURL( "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))")); EXPECT_TRUE(NavigateToURL(shell(), main_url)); @@ -3210,8 +3238,15 @@ // Ensure that when navigating a frame cross-process RenderFrameProxyHosts are // created in the FrameTree skipping the subtree of the navigating frame. + +// Crashes on Win only. https://crbug.com/746055 +#if defined(OS_WIN) +#define MAYBE_ProxyCreationSkipsSubtree DISABLED_ProxyCreationSkipsSubtree +#else +#define MAYBE_ProxyCreationSkipsSubtree ProxyCreationSkipsSubtree +#endif IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, - ProxyCreationSkipsSubtree) { + MAYBE_ProxyCreationSkipsSubtree) { GURL main_url(embedded_test_server()->GetURL( "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))")); EXPECT_TRUE(NavigateToURL(shell(), main_url)); @@ -8380,7 +8415,14 @@ // 2. Attribute injected dynamically via JavaScript // 3. Multiple levels of nesting (A-embed-B-embed-C) // 4. Cross-site subframe navigation -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, AllowFullscreen) { + +// Crashes on Win only. https://crbug.com/746055 +#if defined(OS_WIN) +#define MAYBE_AllowFullscreen DISABLED_AllowFullscreen +#else +#define MAYBE_AllowFullscreen AllowFullscreen +#endif +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, MAYBE_AllowFullscreen) { // Load a page with a cross-site <iframe allowFullscreen>. GURL url_1(embedded_test_server()->GetURL( "a.com", "/page_with_allowfullscreen_frame.html")); @@ -10464,8 +10506,17 @@ // Check that subframes for the same site rendering in unrelated tabs start // sharing processes that are already dedicated to that site when over process // limit. See https://crbug.com/513036. + +// Crashes on Win only. https://crbug.com/746055 +#if defined(OS_WIN) +#define MAYBE_SubframeProcessReuseWhenOverLimit \ + DISABLED_SubframeProcessReuseWhenOverLimit +#else +#define MAYBE_SubframeProcessReuseWhenOverLimit \ + SubframeProcessReuseWhenOverLimit +#endif IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, - SubframeProcessReuseWhenOverLimit) { + MAYBE_SubframeProcessReuseWhenOverLimit) { // Set the process limit to 1. RenderProcessHost::SetMaxRendererProcessCount(1);
diff --git a/content/browser/top_document_isolation_browsertest.cc b/content/browser/top_document_isolation_browsertest.cc index be1fa6e..cb57f06 100644 --- a/content/browser/top_document_isolation_browsertest.cc +++ b/content/browser/top_document_isolation_browsertest.cc
@@ -6,6 +6,7 @@ #include "base/command_line.h" #include "base/test/scoped_feature_list.h" +#include "build/build_config.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/common/content_features.h" @@ -133,7 +134,14 @@ DepictFrameTree(root())); } -IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, NavigateSubframeToTopSite) { +// Crashes on Win only. https://crbug.com/746063 +#if defined(OS_WIN) +#define MAYBE_NavigateSubframeToTopSite DISABLED_NavigateSubframeToTopSite +#else +#define MAYBE_NavigateSubframeToTopSite NavigateSubframeToTopSite +#endif +IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, + MAYBE_NavigateSubframeToTopSite) { if (content::AreAllSitesIsolatedForTesting()) return; // Top Document Isolation is disabled in this mode. @@ -195,8 +203,15 @@ DepictFrameTree(root())); } +// Crashes on Win only. https://crbug.com/746063 +#if defined(OS_WIN) +#define MAYBE_NavigateToSubframeSiteWithPopup \ + DISABLED_NavigateToSubframeSiteWithPopup +#else +#define MAYBE_NavigateToSubframeSiteWithPopup NavigateToSubframeSiteWithPopup +#endif IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, - NavigateToSubframeSiteWithPopup) { + MAYBE_NavigateToSubframeSiteWithPopup) { if (content::AreAllSitesIsolatedForTesting()) return; // Top Document Isolation is disabled in this mode. @@ -283,8 +298,15 @@ DepictFrameTree(root())); } +// Crashes on Win only. https://crbug.com/746063 +#if defined(OS_WIN) +#define MAYBE_NavigateToSubframeSiteWithPopup2 \ + DISABLED_NavigateToSubframeSiteWithPopup2 +#else +#define MAYBE_NavigateToSubframeSiteWithPopup2 NavigateToSubframeSiteWithPopup2 +#endif IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, - NavigateToSubframeSiteWithPopup2) { + MAYBE_NavigateToSubframeSiteWithPopup2) { if (content::AreAllSitesIsolatedForTesting()) return; // Top Document Isolation is disabled in this mode. @@ -399,7 +421,13 @@ DepictFrameTree(root())); } -IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, FramesForSitesInHistory) { +// Crashes on Win only. https://crbug.com/746063 +#if defined(OS_WIN) +#define MAYBE_FrameForSitesInHistory DISABLED_FrameForSitesInHistory +#else +#define MAYBE_FrameForSitesInHistory FrameForSitesInHistory +#endif +IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, MAYBE_FrameForSitesInHistory) { if (content::AreAllSitesIsolatedForTesting()) return; // Top Document Isolation is disabled in this mode.
diff --git a/content/common/media/media_devices.cc b/content/common/media/media_devices.cc index 5eb8a18..90488d0 100644 --- a/content/common/media/media_devices.cc +++ b/content/common/media/media_devices.cc
@@ -44,7 +44,9 @@ MediaDeviceInfo& MediaDeviceInfo::operator=(MediaDeviceInfo&& other) = default; bool operator==(const MediaDeviceInfo& first, const MediaDeviceInfo& second) { - return first.device_id == second.device_id && first.label == second.label; + return first.device_id == second.device_id && first.label == second.label && + first.group_id == second.group_id && + first.video_facing == second.video_facing; } } // namespace content
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc index 39c1e32d..661d5f7a 100644 --- a/content/shell/renderer/layout_test/blink_test_runner.cc +++ b/content/shell/renderer/layout_test/blink_test_runner.cc
@@ -405,37 +405,6 @@ new ShellViewHostMsg_SetPopupBlockingEnabled(routing_id(), block_popups)); } -std::string BlinkTestRunner::makeURLErrorDescription(const WebURLError& error) { - std::string domain = error.domain.Utf8(); - int code = error.reason; - - if (domain == net::kErrorDomain) { - domain = "NSURLErrorDomain"; - switch (error.reason) { - case net::ERR_ABORTED: - code = -999; // NSURLErrorCancelled - break; - case net::ERR_UNSAFE_PORT: - // Our unsafe port checking happens at the network stack level, but we - // make this translation here to match the behavior of stock WebKit. - domain = "WebKitErrorDomain"; - code = 103; - break; - case net::ERR_ADDRESS_INVALID: - case net::ERR_ADDRESS_UNREACHABLE: - case net::ERR_NETWORK_ACCESS_DENIED: - code = -1004; // NSURLErrorCannotConnectToHost - break; - } - } else { - DLOG(WARNING) << "Unknown error domain"; - } - - return base::StringPrintf("<NSError domain %s, code %d, failing URL \"%s\">", - domain.c_str(), code, - error.unreachable_url.GetString().Utf8().data()); -} - void BlinkTestRunner::UseUnfortunateSynchronousResizeMode(bool enable) { UseSynchronousResizeModeVisitor visitor(enable); RenderView::ForEach(&visitor);
diff --git a/content/shell/renderer/layout_test/blink_test_runner.h b/content/shell/renderer/layout_test/blink_test_runner.h index 22c3f718..7662edb 100644 --- a/content/shell/renderer/layout_test/blink_test_runner.h +++ b/content/shell/renderer/layout_test/blink_test_runner.h
@@ -84,7 +84,6 @@ test_runner::TestPreferences* Preferences() override; void ApplyPreferences() override; void SetPopupBlockingEnabled(bool block_popups) override; - virtual std::string makeURLErrorDescription(const blink::WebURLError& error); void UseUnfortunateSynchronousResizeMode(bool enable) override; void EnableAutoResizeMode(const blink::WebSize& min_size, const blink::WebSize& max_size) override;
diff --git a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm index cc329b5..6355a937 100644 --- a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm +++ b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
@@ -46,6 +46,58 @@ } } +void RecordSigninImpressionWithAccountUserActionForAccessPoint( + signin_metrics::AccessPoint access_point) { + switch (access_point) { + case signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER: + base::RecordAction(base::UserMetricsAction( + "Signin_ImpressionWithAccount_FromBookmarkManager")); + break; + case signin_metrics::AccessPoint::ACCESS_POINT_RECENT_TABS: + base::RecordAction(base::UserMetricsAction( + "Signin_ImpressionWithAccount_FromRecentTabs")); + break; + case signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS: + base::RecordAction( + base::UserMetricsAction("Signin_ImpressionWithAccount_FromSettings")); + break; + case signin_metrics::AccessPoint::ACCESS_POINT_TAB_SWITCHER: + base::RecordAction(base::UserMetricsAction( + "Signin_ImpressionWithAccount_FromTabSwitcher")); + break; + default: + NOTREACHED() << "Unexpected value for access point " + << static_cast<int>(access_point); + break; + } +} + +void RecordSigninImpressionWithNoAccountUserActionForAccessPoint( + signin_metrics::AccessPoint access_point) { + switch (access_point) { + case signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER: + base::RecordAction(base::UserMetricsAction( + "Signin_ImpressionWithNoAccount_FromBookmarkManager")); + break; + case signin_metrics::AccessPoint::ACCESS_POINT_RECENT_TABS: + base::RecordAction(base::UserMetricsAction( + "Signin_ImpressionWithNoAccount_FromRecentTabs")); + break; + case signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS: + base::RecordAction(base::UserMetricsAction( + "Signin_ImpressionWithNoAccount_FromSettings")); + break; + case signin_metrics::AccessPoint::ACCESS_POINT_TAB_SWITCHER: + base::RecordAction(base::UserMetricsAction( + "Signin_ImpressionWithNoAccount_FromTabSwitcher")); + break; + default: + NOTREACHED() << "Unexpected value for access point " + << static_cast<int>(access_point); + break; + } +} + void RecordSigninUserActionForAccessPoint( signin_metrics::AccessPoint access_point) { switch (access_point) { @@ -215,6 +267,11 @@ if (identities.count != 0) { [self selectIdentity:identities[0]]; } + if (_defaultIdentity) { + RecordSigninImpressionWithAccountUserActionForAccessPoint(accessPoint); + } else { + RecordSigninImpressionWithNoAccountUserActionForAccessPoint(accessPoint); + } _identityServiceObserver = base::MakeUnique<ChromeIdentityServiceObserverBridge>(self); _browserProviderObserver =
diff --git a/ios/chrome/today_extension/today_metrics_logger.mm b/ios/chrome/today_extension/today_metrics_logger.mm index 7eb52e32..55c2ddc 100644 --- a/ios/chrome/today_extension/today_metrics_logger.mm +++ b/ios/chrome/today_extension/today_metrics_logger.mm
@@ -250,7 +250,8 @@ log_->RecordEnvironment( std::vector<std::unique_ptr<metrics::MetricsProvider>>(), - [install_date longLongValue], [enabled_date longLongValue]); + std::vector<variations::ActiveGroupId>(), [install_date longLongValue], + [enabled_date longLongValue]); return true; }
diff --git a/ios/third_party/material_components_ios/README.chromium b/ios/third_party/material_components_ios/README.chromium index 90acb03..cbb387d 100644 --- a/ios/third_party/material_components_ios/README.chromium +++ b/ios/third_party/material_components_ios/README.chromium
@@ -1,7 +1,7 @@ Name: Material Components for iOS URL: https://github.com/material-components/material-components-ios Version: 0 -Revision: d08f9c0c1926fce2964cffbc163385896c86798a +Revision: cb191e7c014cc871b5351a3911a1d0bc71b71699 License: Apache 2.0 License File: LICENSE Security Critical: yes
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn index ce14ab8..d84a0ce 100644 --- a/ios/web/BUILD.gn +++ b/ios/web/BUILD.gn
@@ -254,16 +254,6 @@ "web_state/ui/wk_web_view_configuration_provider.mm", "web_state/web_controller_observer_bridge.h", "web_state/web_controller_observer_bridge.mm", - "web_state/web_state.mm", - "web_state/web_state_delegate.mm", - "web_state/web_state_delegate_bridge.mm", - "web_state/web_state_impl.h", - "web_state/web_state_impl.mm", - "web_state/web_state_observer.mm", - "web_state/web_state_observer_bridge.mm", - "web_state/web_state_policy_decider.mm", - "web_state/web_state_weak_ptr_factory.h", - "web_state/web_state_weak_ptr_factory.mm", "web_state/web_view_internal_creation_util.h", "web_state/web_view_internal_creation_util.mm", "web_state/wk_web_view_security_util.h", @@ -338,6 +328,16 @@ "web_state/ui/crw_web_controller.mm", "web_state/ui/crw_web_controller_container_view.h", "web_state/ui/crw_web_controller_container_view.mm", + "web_state/web_state.mm", + "web_state/web_state_delegate.mm", + "web_state/web_state_delegate_bridge.mm", + "web_state/web_state_impl.h", + "web_state/web_state_impl.mm", + "web_state/web_state_observer.mm", + "web_state/web_state_observer_bridge.mm", + "web_state/web_state_policy_decider.mm", + "web_state/web_state_weak_ptr_factory.h", + "web_state/web_state_weak_ptr_factory.mm", ] libs = [
diff --git a/ios/web/web_state/web_state.mm b/ios/web/web_state/web_state.mm index 55ece67..ad5791d 100644 --- a/ios/web/web_state/web_state.mm +++ b/ios/web/web_state/web_state.mm
@@ -4,10 +4,6 @@ #import "ios/web/public/web_state/web_state.h" -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - namespace web { WebState::CreateParams::CreateParams(web::BrowserState* browser_state)
diff --git a/ios/web/web_state/web_state_delegate.mm b/ios/web/web_state/web_state_delegate.mm index 2c58355..c6a2def0 100644 --- a/ios/web/web_state/web_state_delegate.mm +++ b/ios/web/web_state/web_state_delegate.mm
@@ -6,10 +6,6 @@ #import "ios/web/public/web_state/web_state.h" -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - namespace web { WebStateDelegate::WebStateDelegate() {}
diff --git a/ios/web/web_state/web_state_delegate_bridge.mm b/ios/web/web_state/web_state_delegate_bridge.mm index b4c1255..797e9f46 100644 --- a/ios/web/web_state/web_state_delegate_bridge.mm +++ b/ios/web/web_state/web_state_delegate_bridge.mm
@@ -7,10 +7,6 @@ #include "base/logging.h" #import "ios/web/public/web_state/context_menu_params.h" -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - namespace web { WebStateDelegateBridge::WebStateDelegateBridge(id<CRWWebStateDelegate> delegate)
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm index c6a673e..676b8af 100644 --- a/ios/web/web_state/web_state_impl.mm +++ b/ios/web/web_state/web_state_impl.mm
@@ -44,10 +44,6 @@ #include "net/http/http_response_headers.h" #include "ui/gfx/image/image.h" -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - namespace web { /* static */ @@ -177,7 +173,7 @@ void WebStateImpl::SetWebController(CRWWebController* web_controller) { [web_controller_ close]; - web_controller_.reset(web_controller); + web_controller_.reset([web_controller retain]); } void WebStateImpl::OnTitleChanged() {
diff --git a/ios/web/web_state/web_state_observer.mm b/ios/web/web_state/web_state_observer.mm index 4c24630..1408a6e8 100644 --- a/ios/web/web_state/web_state_observer.mm +++ b/ios/web/web_state/web_state_observer.mm
@@ -7,10 +7,6 @@ #include "ios/web/public/load_committed_details.h" #import "ios/web/public/web_state/web_state.h" -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - namespace web { WebStateObserver::WebStateObserver(WebState* web_state) : web_state_(nullptr) {
diff --git a/ios/web/web_state/web_state_observer_bridge.mm b/ios/web/web_state/web_state_observer_bridge.mm index 12de262..73982ff 100644 --- a/ios/web/web_state/web_state_observer_bridge.mm +++ b/ios/web/web_state/web_state_observer_bridge.mm
@@ -4,10 +4,6 @@ #import "ios/web/public/web_state/web_state_observer_bridge.h" -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - namespace web { WebStateObserverBridge::WebStateObserverBridge(web::WebState* webState,
diff --git a/ios/web/web_state/web_state_policy_decider.mm b/ios/web/web_state/web_state_policy_decider.mm index 5f3e69d..f061dfa12 100644 --- a/ios/web/web_state/web_state_policy_decider.mm +++ b/ios/web/web_state/web_state_policy_decider.mm
@@ -7,10 +7,6 @@ #import "ios/web/public/web_state/web_state.h" #import "ios/web/web_state/web_state_impl.h" -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - namespace web { WebStatePolicyDecider::WebStatePolicyDecider(WebState* web_state)
diff --git a/ios/web/web_state/web_state_weak_ptr_factory.mm b/ios/web/web_state/web_state_weak_ptr_factory.mm index 2b94ef4..3b93e4b 100644 --- a/ios/web/web_state/web_state_weak_ptr_factory.mm +++ b/ios/web/web_state/web_state_weak_ptr_factory.mm
@@ -6,10 +6,6 @@ #import "ios/web/public/web_state/web_state.h" -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - namespace web { // static
diff --git a/ios/web/webui/web_ui_mojo_inttest.mm b/ios/web/webui/web_ui_mojo_inttest.mm index 4e64d41e..0d240d8c 100644 --- a/ios/web/webui/web_ui_mojo_inttest.mm +++ b/ios/web/webui/web_ui_mojo_inttest.mm
@@ -147,23 +147,6 @@ new TestWebUIControllerFactory(ui_handler_.get())); } - void TearDown() override { - @autoreleasepool { - // WebState owns CRWWebUIManager. When WebState is destroyed, - // CRWWebUIManager is autoreleased and will be destroyed upon autorelease - // pool purge. However in this test, WebTest destructor is called before - // PlatformTest, thus CRWWebUIManager outlives the WebThreadBundle. - // However, CRWWebUIManager owns a URLFetcherImpl, which DCHECKs that its - // destructor is called on UI web thread. Hence, URLFetcherImpl has to - // outlive the WebThreadBundle, since [NSThread mainThread] will not be - // WebThread::UI once WebThreadBundle is destroyed. - web_state_.reset(); - ui_handler_.reset(); - } - - WebIntTest::TearDown(); - } - // Returns WebState which loads test WebUI page. WebStateImpl* web_state() { return web_state_.get(); } // Returns UI handler which communicates with WebUI page. @@ -184,33 +167,31 @@ #endif // TODO(crbug.com/720098): Enable this test on device. TEST_F(WebUIMojoTest, MAYBE_MessageExchange) { - @autoreleasepool { - web_state()->SetWebUsageEnabled(true); - web_state()->GetView(); // WebState won't load URL without view. - GURL url(url::SchemeHostPort(kTestWebUIScheme, kTestWebUIURLHost, 0) - .Serialize()); - NavigationManager::WebLoadParams load_params(url); - web_state()->GetNavigationManager()->LoadURLWithParams(load_params); + web_state()->SetWebUsageEnabled(true); + web_state()->GetView(); // WebState won't load URL without view. + GURL url( + url::SchemeHostPort(kTestWebUIScheme, kTestWebUIURLHost, 0).Serialize()); + NavigationManager::WebLoadParams load_params(url); + web_state()->GetNavigationManager()->LoadURLWithParams(load_params); - // Wait until |TestUIHandler| receives "fin" message from WebUI page. - bool fin_received = testing::WaitUntilConditionOrTimeout(kMessageTimeout, ^{ - // Flush any pending tasks. Don't RunUntilIdle() because - // RunUntilIdle() is incompatible with mojo::SimpleWatcher's - // automatic arming behavior, which Mojo JS still depends upon. - // - // TODO(crbug.com/701875): Introduce the full watcher API to JS and get - // rid of this hack. - base::RunLoop loop; - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, - loop.QuitClosure()); - loop.Run(); - return test_ui_handler()->IsFinReceived(); - }); + // Wait until |TestUIHandler| receives "fin" message from WebUI page. + bool fin_received = testing::WaitUntilConditionOrTimeout(kMessageTimeout, ^{ + // Flush any pending tasks. Don't RunUntilIdle() because + // RunUntilIdle() is incompatible with mojo::SimpleWatcher's + // automatic arming behavior, which Mojo JS still depends upon. + // + // TODO(crbug.com/701875): Introduce the full watcher API to JS and get rid + // of this hack. + base::RunLoop loop; + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + loop.QuitClosure()); + loop.Run(); + return test_ui_handler()->IsFinReceived(); + }); - ASSERT_TRUE(fin_received); - EXPECT_FALSE(web_state()->IsLoading()); - EXPECT_EQ(url, web_state()->GetLastCommittedURL()); - } + ASSERT_TRUE(fin_received); + EXPECT_FALSE(web_state()->IsLoading()); + EXPECT_EQ(url, web_state()->GetLastCommittedURL()); } } // namespace web
diff --git a/media/midi/BUILD.gn b/media/midi/BUILD.gn index 5bbf810..5e40368 100644 --- a/media/midi/BUILD.gn +++ b/media/midi/BUILD.gn
@@ -156,6 +156,17 @@ } } + if (is_chromeos) { + # CrOS version can be used with target_os="chromeos" on Linux. + # MIDI Service client library should be added here. We would have a separate + # build flag, use_midis, to use the real MIDI Service on Chrome OS device + # builds, and add a mocked service for unit tests to run on Linux. + sources += [ + "chromeos/midi_manager_cros.cc", + "chromeos/midi_manager_cros.h", + ] + } + if (use_alsa && use_udev) { deps += [ "//crypto",
diff --git a/media/midi/chromeos/midi_manager_cros.cc b/media/midi/chromeos/midi_manager_cros.cc new file mode 100644 index 0000000..b554e0ab --- /dev/null +++ b/media/midi/chromeos/midi_manager_cros.cc
@@ -0,0 +1,24 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/midi/chromeos/midi_manager_cros.h" + +#include "media/midi/midi_manager_alsa.h" +#include "media/midi/midi_switches.h" + +namespace midi { + +MidiManagerCros::MidiManagerCros(MidiService* service) : MidiManager(service) {} + +MidiManagerCros::~MidiManagerCros() = default; + +MidiManager* MidiManager::Create(MidiService* service) { + // Note: Because of crbug.com/719489, chrome://flags does not affect + // base::FeatureList::IsEnabled when you build target_os="chromeos" on Linux. + if (base::FeatureList::IsEnabled(features::kMidiManagerCros)) + return new MidiManagerCros(service); + return new MidiManagerAlsa(service); +} + +} // namespace midi
diff --git a/media/midi/chromeos/midi_manager_cros.h b/media/midi/chromeos/midi_manager_cros.h new file mode 100644 index 0000000..4a8f94a --- /dev/null +++ b/media/midi/chromeos/midi_manager_cros.h
@@ -0,0 +1,23 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_MIDI_CHROMEOS_MIDI_MANAGER_CROS_H_ +#define MEDIA_MIDI_CHROMEOS_MIDI_MANAGER_CROS_H_ + +#include "media/midi/midi_export.h" +#include "media/midi/midi_manager.h" + +namespace midi { + +class MIDI_EXPORT MidiManagerCros final : public MidiManager { + public: + explicit MidiManagerCros(MidiService* service); + ~MidiManagerCros() override; + + DISALLOW_COPY_AND_ASSIGN(MidiManagerCros); +}; + +} // namespace midi + +#endif // MEDIA_MIDI_CHROMEOS_MIDI_MANAGER_CROS_H_
diff --git a/media/midi/midi_manager_alsa.cc b/media/midi/midi_manager_alsa.cc index 1ef6e569..dc33c29 100644 --- a/media/midi/midi_manager_alsa.cc +++ b/media/midi/midi_manager_alsa.cc
@@ -25,6 +25,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/time/time.h" +#include "build/build_config.h" #include "crypto/sha2.h" #include "media/midi/midi_port_info.h" #include "media/midi/midi_service.h" @@ -164,6 +165,8 @@ MidiManagerAlsa::MidiManagerAlsa(MidiService* service) : MidiManager(service) {} MidiManagerAlsa::~MidiManagerAlsa() { + base::AutoLock lock(lazy_init_member_lock_); + // Extra CHECK to verify all members are already reset. CHECK(!in_client_); CHECK(!out_client_); @@ -178,6 +181,8 @@ return CompleteInitialization(Result::INITIALIZATION_ERROR); } + base::AutoLock lock(lazy_init_member_lock_); + // Create client handles. snd_seq_t* tmp_seq = nullptr; int err = @@ -296,15 +301,19 @@ } void MidiManagerAlsa::Finalize() { - // Close the out client. This will trigger the event thread to stop, - // because of SND_SEQ_EVENT_CLIENT_EXIT. - out_client_.reset(); + { + base::AutoLock lock(out_client_lock_); + // Close the out client. This will trigger the event thread to stop, + // because of SND_SEQ_EVENT_CLIENT_EXIT. + out_client_.reset(); + } // Ensure that no task is running any more. bool result = service()->task_service()->UnbindInstance(); CHECK(result); // Destruct the other stuff we initialized in StartInitialization(). + base::AutoLock lock(lazy_init_member_lock_); udev_monitor_.reset(); udev_.reset(); decoder_.reset(); @@ -857,6 +866,9 @@ base::AutoLock lock(out_ports_lock_); auto it = out_ports_.find(port_index); if (it != out_ports_.end()) { + base::AutoLock lock(out_client_lock_); + if (!out_client_) + return; snd_seq_ev_set_source(&event, it->second); snd_seq_ev_set_subs(&event); snd_seq_ev_set_direct(&event); @@ -1377,8 +1389,10 @@ return true; } +#if !defined(OS_CHROMEOS) MidiManager* MidiManager::Create(MidiService* service) { return new MidiManagerAlsa(service); } +#endif } // namespace midi
diff --git a/media/midi/midi_manager_alsa.h b/media/midi/midi_manager_alsa.h index de48824..c563584 100644 --- a/media/midi/midi_manager_alsa.h +++ b/media/midi/midi_manager_alsa.h
@@ -417,10 +417,15 @@ // wait for our information from ALSA and udev to get back in sync. int alsa_card_midi_count_ = 0; + // Guards members below. They are initialized before posting any tasks running + // on TaskRunner, and finalized after all posted tasks run. + base::Lock lazy_init_member_lock_; + // ALSA seq handles and ids. ScopedSndSeqPtr in_client_; int in_client_id_; - ScopedSndSeqPtr out_client_; + base::Lock out_client_lock_; // guards out_client_ + ScopedSndSeqPtr out_client_; // guarded by out_client_lock_ int out_client_id_; int in_port_id_;
diff --git a/media/midi/midi_switches.cc b/media/midi/midi_switches.cc index 96e7974b..c64c544 100644 --- a/media/midi/midi_switches.cc +++ b/media/midi/midi_switches.cc
@@ -18,6 +18,11 @@ base::FEATURE_DISABLED_BY_DEFAULT}; #endif +#if defined(OS_CHROMEOS) +const base::Feature kMidiManagerCros{"MidiManagerCros", + base::FEATURE_DISABLED_BY_DEFAULT}; +#endif + const base::Feature kMidiManagerDynamicInstantiation{ "MidiManagerDynamicInstantiation", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/media/midi/midi_switches.h b/media/midi/midi_switches.h index b5e45b0..e6b3526 100644 --- a/media/midi/midi_switches.h +++ b/media/midi/midi_switches.h
@@ -22,6 +22,10 @@ MIDI_EXPORT extern const base::Feature kMidiManagerWinrt; #endif +#if defined(OS_CHROMEOS) +MIDI_EXPORT extern const base::Feature kMidiManagerCros; +#endif + MIDI_EXPORT extern const base::Feature kMidiManagerDynamicInstantiation; } // namespace features
diff --git a/services/ui/ime/test_ime_driver/test_ime_driver.cc b/services/ui/ime/test_ime_driver/test_ime_driver.cc index 8d1aa63..8e17f1f 100644 --- a/services/ui/ime/test_ime_driver/test_ime_driver.cc +++ b/services/ui/ime/test_ime_driver/test_ime_driver.cc
@@ -4,6 +4,8 @@ #include "services/ui/ime/test_ime_driver/test_ime_driver.h" +#include <utility> + #include "mojo/public/cpp/bindings/strong_binding.h" #include "services/ui/public/interfaces/ime/ime.mojom.h" @@ -21,14 +23,14 @@ void OnTextInputTypeChanged(TextInputType text_input_type) override {} void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override {} void ProcessKeyEvent(std::unique_ptr<Event> key_event, - const ProcessKeyEventCallback& callback) override { + ProcessKeyEventCallback callback) override { DCHECK(key_event->IsKeyEvent()); if (key_event->AsKeyEvent()->is_char()) { client_->InsertChar(std::move(key_event)); - callback.Run(true); + std::move(callback).Run(true); } else { - callback.Run(false); + std::move(callback).Run(false); } } void CancelComposition() override {}
diff --git a/services/ui/public/interfaces/ime/BUILD.gn b/services/ui/public/interfaces/ime/BUILD.gn index c84682d..85909fb 100644 --- a/services/ui/public/interfaces/ime/BUILD.gn +++ b/services/ui/public/interfaces/ime/BUILD.gn
@@ -15,9 +15,6 @@ "//ui/gfx/geometry/mojo", "//ui/gfx/range/mojo", ] - - # TODO(crbug.com/714018): Convert the implementation to use OnceCallback. - use_once_callback = false } mojom("test_interfaces") { @@ -28,7 +25,4 @@ public_deps = [ ":ime", ] - - # TODO(crbug.com/714018): Convert the implementation to use OnceCallback. - use_once_callback = false }
diff --git a/services/ui/public/interfaces/ime/ime_struct_traits_unittest.cc b/services/ui/public/interfaces/ime/ime_struct_traits_unittest.cc index 4497652..cfaec6f8 100644 --- a/services/ui/public/interfaces/ime/ime_struct_traits_unittest.cc +++ b/services/ui/public/interfaces/ime/ime_struct_traits_unittest.cc
@@ -4,6 +4,8 @@ #include "services/ui/public/interfaces/ime/ime_struct_traits.h" +#include <utility> + #include "base/message_loop/message_loop.h" #include "base/strings/utf_string_conversions.h" #include "mojo/public/cpp/bindings/binding_set.h" @@ -32,12 +34,12 @@ private: // mojom::IMEStructTraitsTest: void EchoTextInputMode(TextInputMode in, - const EchoTextInputModeCallback& callback) override { - callback.Run(in); + EchoTextInputModeCallback callback) override { + std::move(callback).Run(in); } void EchoTextInputType(TextInputType in, - const EchoTextInputTypeCallback& callback) override { - callback.Run(in); + EchoTextInputTypeCallback callback) override { + std::move(callback).Run(in); } base::MessageLoop loop_; // A MessageLoop is needed for Mojo IPC to work.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/skip-waiting-installed.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/skip-waiting-installed.https.html index 93dc06d..21e26be5 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/skip-waiting-installed.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/skip-waiting-installed.https.html
@@ -20,15 +20,14 @@ assert_equals( message, 'PASS', 'skipWaiting promise should be resolved with undefined'); - - assert_equals(registration.active.scriptURL, normalizeURL(url2), - 'skipWaiting should make worker become active'); }); var saw_controllerchanged = new Promise(function(resolve) { oncontrollerchanged = function() { assert_equals( frame_sw.controller.scriptURL, normalizeURL(url2), 'Controller scriptURL should change to the second one'); + assert_equals(registration.active.scriptURL, normalizeURL(url2), + 'Worker which calls skipWaiting should be active by controllerchange'); resolve(); }; });
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-clear-function-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-clear-function-expected.txt index 816acea..a30d1dc 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-clear-function-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/console/console-clear-function-expected.txt
@@ -1,13 +1,31 @@ CONSOLE MESSAGE: line 10: one CONSOLE MESSAGE: line 11: two CONSOLE MESSAGE: line 12: three +CONSOLE MESSAGE: line 10: one +CONSOLE MESSAGE: line 11: two +CONSOLE MESSAGE: line 12: three Tests that console is cleared via console.clear() method Bug 101021 + +Running: clearFromConsoleAPI === Before clear === console-clear-function.html:10 one console-clear-function.html:11 two console-clear-function.html:12 three === After clear === -console-clear-function.html:19 Console was cleared +console-clear-function.html:17 Console was cleared + +Running: shouldNotClearWithPreserveLog +=== Before clear === +console-clear-function.html:17 Console was cleared +console-clear-function.html:10 one +console-clear-function.html:11 two +console-clear-function.html:12 three +=== After clear === +console-clear-function.html:17 Console was cleared +console-clear-function.html:10 one +console-clear-function.html:11 two +console-clear-function.html:12 three +console-clear-function.html:17 console.clear() was prevented due to 'Preserve log'
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-clear-function.html b/third_party/WebKit/LayoutTests/inspector/console/console-clear-function.html index 691ce56..d282e05 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-clear-function.html +++ b/third_party/WebKit/LayoutTests/inspector/console/console-clear-function.html
@@ -12,23 +12,40 @@ console.log("three"); } -log(); - -function foo() +function clearConsoleFromPage() { console.clear(); } async function test() { - InspectorTest.addResult("=== Before clear ==="); - InspectorTest.dumpConsoleMessages(); + InspectorTest.runTestSuite([ + async function clearFromConsoleAPI(next) { + await InspectorTest.RuntimeAgent.evaluate("log();"); + InspectorTest.addResult("=== Before clear ==="); + InspectorTest.dumpConsoleMessages(); - await InspectorTest.RuntimeAgent.evaluate("foo();"); + await InspectorTest.RuntimeAgent.evaluate("clearConsoleFromPage();"); - InspectorTest.addResult("=== After clear ==="); - InspectorTest.dumpConsoleMessages(); - InspectorTest.completeTest(); + InspectorTest.addResult("=== After clear ==="); + InspectorTest.dumpConsoleMessages(); + next(); + }, + + async function shouldNotClearWithPreserveLog(next) { + await InspectorTest.RuntimeAgent.evaluate("log();"); + InspectorTest.addResult("=== Before clear ==="); + InspectorTest.dumpConsoleMessages(); + Common.moduleSetting("preserveConsoleLog").set(true); + + await InspectorTest.RuntimeAgent.evaluate("clearConsoleFromPage();"); + + InspectorTest.addResult("=== After clear ==="); + InspectorTest.dumpConsoleMessages(); + Common.moduleSetting("preserveConsoleLog").set(false); + next(); + } + ]); } </script> @@ -38,7 +55,7 @@ <p> Tests that console is cleared via console.clear() method </p> -<a href="https://bugs.webkit.org/show_bug.cgi?id=101021">Bug 101021 </a> +<a href="https://bugs.webkit.org/show_bug.cgi?id=101021">Bug 101021</a> </body> </html>
diff --git a/third_party/WebKit/PerformanceTests/CSS/ChangeStyleDeepTree.html b/third_party/WebKit/PerformanceTests/CSS/ChangeStyleDeepTree.html index 5947a8e..f56ac7c 100644 --- a/third_party/WebKit/PerformanceTests/CSS/ChangeStyleDeepTree.html +++ b/third_party/WebKit/PerformanceTests/CSS/ChangeStyleDeepTree.html
@@ -28,9 +28,9 @@ run: function() { for (var i=0; i < length; i++) { allElements[i].id = "item"; - PerfTestRunner.forceLayout(allElements[i]); + forceStyleRecalc(allElements[i]); allElements[i].id = ""; - PerfTestRunner.forceLayout(allElements[i]); + forceStyleRecalc(allElements[i]); } }, tracingCategories: 'blink',
diff --git a/third_party/WebKit/PerformanceTests/CSS/ChangeStyleNestedPseudoSelector.html b/third_party/WebKit/PerformanceTests/CSS/ChangeStyleNestedPseudoSelector.html new file mode 100644 index 0000000..863c2af --- /dev/null +++ b/third_party/WebKit/PerformanceTests/CSS/ChangeStyleNestedPseudoSelector.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<head> + <script src="../resources/runner.js"></script> + <script src="resources/utils.js"></script> +</head> +<body> +</body> + <script> + createRegularDOMTree(); + PerfTestRunner.measureTime({ + description: "Measures the performance of a solo pseudo selector applied on a grandchild of a div.", + run: function() { + var rule = applyCSSRule("div div div:after { content: 'after'; }"); + forceStyleRecalc(document.body); + rule.remove(); + forceStyleRecalc(document.body); + }, + tracingCategories: 'blink', + traceEventsToMeasure: [ + 'Document::updateStyle', + 'Document::recalcStyle', + 'Document::rebuildLayoutTree' + ] + }); + </script> +</html> \ No newline at end of file
diff --git a/third_party/WebKit/PerformanceTests/CSS/ChangeStylePairOfNthChildSelector.html b/third_party/WebKit/PerformanceTests/CSS/ChangeStylePairOfNthChildSelector.html new file mode 100644 index 0000000..8f5bcdf2 --- /dev/null +++ b/third_party/WebKit/PerformanceTests/CSS/ChangeStylePairOfNthChildSelector.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<head> + <script src="../resources/runner.js"></script> + <script src="resources/utils.js"></script> +</head> +<body> +</body> + <script> + createRegularDOMTree(); + PerfTestRunner.measureTime({ + description: "Measures the performance of a pair of nth-child selectors.", + run: function() { + var rule = applyCSSRule("div:nth-child(1) div:nth-child(1) div { color: red; }"); + forceStyleRecalc(document.body); + rule.remove(); + forceStyleRecalc(document.body); + }, + tracingCategories: 'blink', + traceEventsToMeasure: [ + 'Document::updateStyle', + 'Document::recalcStyle', + 'Document::rebuildLayoutTree' + ] + }); + </script> +</html> \ No newline at end of file
diff --git a/third_party/WebKit/PerformanceTests/CSS/ChangeStyleShallowTree.html b/third_party/WebKit/PerformanceTests/CSS/ChangeStyleShallowTree.html index 554dfca..7a9a8ef 100644 --- a/third_party/WebKit/PerformanceTests/CSS/ChangeStyleShallowTree.html +++ b/third_party/WebKit/PerformanceTests/CSS/ChangeStyleShallowTree.html
@@ -28,9 +28,9 @@ run: function() { for (var i=0; i < length; i++) { allElements[i].id = "item"; - PerfTestRunner.forceLayout(allElements[i]); + forceStyleRecalc(allElements[i]); allElements[i].id = ""; - PerfTestRunner.forceLayout(allElements[i]); + forceStyleRecalc(allElements[i]); } }, tracingCategories: 'blink',
diff --git a/third_party/WebKit/PerformanceTests/CSS/ChangeStyleSingleNthChildSelector.html b/third_party/WebKit/PerformanceTests/CSS/ChangeStyleSingleNthChildSelector.html new file mode 100644 index 0000000..d2ba23d --- /dev/null +++ b/third_party/WebKit/PerformanceTests/CSS/ChangeStyleSingleNthChildSelector.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<head> + <script src="../resources/runner.js"></script> + <script src="resources/utils.js"></script> +</head> +<body> +</body> + <script> + createRegularDOMTree(); + PerfTestRunner.measureTime({ + description: "Measures the performance of a nth-child selector.", + run: function() { + var rule = applyCSSRule("div:nth-child(1) div { color: red; }"); + forceStyleRecalc(document.body); + rule.remove(); + forceStyleRecalc(document.body); + }, + tracingCategories: 'blink', + traceEventsToMeasure: [ + 'Document::updateStyle', + 'Document::recalcStyle', + 'Document::rebuildLayoutTree' + ] + }); + </script> +</html> \ No newline at end of file
diff --git a/third_party/WebKit/PerformanceTests/CSS/ChangeStyleSinglePseudoSelector.html b/third_party/WebKit/PerformanceTests/CSS/ChangeStyleSinglePseudoSelector.html new file mode 100644 index 0000000..335a15e8f2 --- /dev/null +++ b/third_party/WebKit/PerformanceTests/CSS/ChangeStyleSinglePseudoSelector.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<head> + <script src="../resources/runner.js"></script> + <script src="resources/utils.js"></script> +</head> +<body> +</body> + <script> + createRegularDOMTree(); + PerfTestRunner.measureTime({ + description: "Measures the performance of a solo pseudo selector.", + run: function() { + var rule = applyCSSRule("div:after { content: 'after'; }"); + forceStyleRecalc(document.body); + rule.remove(); + forceStyleRecalc(document.body); + }, + tracingCategories: 'blink', + traceEventsToMeasure: [ + 'Document::updateStyle', + 'Document::recalcStyle', + 'Document::rebuildLayoutTree' + ] + }); + </script> +</html> \ No newline at end of file
diff --git a/third_party/WebKit/PerformanceTests/CSS/resources/utils.js b/third_party/WebKit/PerformanceTests/CSS/resources/utils.js index cc06c0a..e6e39cba 100644 --- a/third_party/WebKit/PerformanceTests/CSS/resources/utils.js +++ b/third_party/WebKit/PerformanceTests/CSS/resources/utils.js
@@ -9,9 +9,25 @@ } function createDeepDOMTree() { - createDOMTree(document.body, 2, 10); + createDOMTree(document.body, 2, 10); +} + +function forceStyleRecalc(node) { + node.offsetTop; // forces style recalc } function createShallowDOMTree() { - createDOMTree(document.body, 10, 2); -} \ No newline at end of file + createDOMTree(document.body, 10, 2); +} + +function createRegularDOMTree() { + createDOMTree(document.body, 6, 6); +} + +function applyCSSRule(rule) { + var css = document.createElement("style"); + css.type = "text/css"; + css.innerHTML = rule; + document.body.appendChild(css); + return css; +}
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.cpp b/third_party/WebKit/Source/core/editing/FrameSelection.cpp index 185716d..857e7dca 100644 --- a/third_party/WebKit/Source/core/editing/FrameSelection.cpp +++ b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
@@ -296,20 +296,6 @@ Event::Create(EventTypeNames::selectionchange)); } -void FrameSelection::SetSelection(const SelectionInFlatTree& new_selection, - SetSelectionOptions options, - CursorAlignOnScroll align, - TextGranularity granularity) { - new_selection.AssertValidFor(GetDocument()); - SelectionInDOMTree::Builder builder; - builder.SetAffinity(new_selection.Affinity()) - .SetBaseAndExtent(ToPositionInDOMTree(new_selection.Base()), - ToPositionInDOMTree(new_selection.Extent())) - .SetIsDirectional(new_selection.IsDirectional()) - .SetIsHandleVisible(new_selection.IsHandleVisible()); - return SetSelection(builder.Build(), options, align, granularity); -} - void FrameSelection::NodeChildrenWillBeRemoved(ContainerNode& container) { if (!container.InActiveDocument()) return;
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.h b/third_party/WebKit/Source/core/editing/FrameSelection.h index 4f0b8c95..e897f56 100644 --- a/third_party/WebKit/Source/core/editing/FrameSelection.h +++ b/third_party/WebKit/Source/core/editing/FrameSelection.h
@@ -114,11 +114,6 @@ SetSelectionOptions = kCloseTyping | kClearTypingStyle, CursorAlignOnScroll = CursorAlignOnScroll::kIfNeeded, TextGranularity = TextGranularity::kCharacter); - - void SetSelection(const SelectionInFlatTree&, - SetSelectionOptions = kCloseTyping | kClearTypingStyle, - CursorAlignOnScroll = CursorAlignOnScroll::kIfNeeded, - TextGranularity = TextGranularity::kCharacter); void SelectAll(EUserTriggered = kNotUserTriggered); void Clear(); bool IsHidden() const;
diff --git a/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp b/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp index eafe272..b6dd9d6 100644 --- a/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp +++ b/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp
@@ -166,9 +166,10 @@ // Select "two" for selection in DOM tree // Select "twoone" for selection in Flat tree Selection().SetSelection( - SelectionInFlatTree::Builder() - .Collapse(PositionInFlatTree(host, 0)) - .Extend(PositionInFlatTree(GetDocument().body(), 2)) + SelectionInDOMTree::Builder() + .Collapse(ToPositionInDOMTree(PositionInFlatTree(host, 0))) + .Extend( + ToPositionInDOMTree(PositionInFlatTree(GetDocument().body(), 2))) .Build()); Selection().Modify(FrameSelection::kAlterationExtend, kDirectionForward, TextGranularity::kWord); @@ -450,9 +451,8 @@ Node* text_node = shadow_root->firstChild(); Selection().SetSelection( - SelectionInFlatTree::Builder() - .SetBaseAndExtent(PositionInFlatTree(text_node, 0), - PositionInFlatTree(text_node, 3)) + SelectionInDOMTree::Builder() + .SetBaseAndExtent(Position(text_node, 0), Position(text_node, 3)) .Build()); EXPECT_EQ_SELECTED_TEXT("hey"); EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
diff --git a/third_party/WebKit/Source/core/editing/LayoutSelection.cpp b/third_party/WebKit/Source/core/editing/LayoutSelection.cpp index 72ecb59..dfd7b6f 100644 --- a/third_party/WebKit/Source/core/editing/LayoutSelection.cpp +++ b/third_party/WebKit/Source/core/editing/LayoutSelection.cpp
@@ -42,6 +42,9 @@ end_offset_(end_offset) { DCHECK(start_layout_object_); DCHECK(end_layout_object_); + traverse_stop_ = end_layout_object_->ChildAt(end_offset); + if (!traverse_stop_) + traverse_stop_ = end_layout_object_->NextInPreOrderAfterChildren(); if (start_layout_object_ != end_layout_object_) return; DCHECK_LT(start_offset_, end_offset_); @@ -79,12 +82,8 @@ current_ = nullptr; return; } + range_ = range; current_ = range->StartLayoutObject(); - included_end_ = range->EndLayoutObject(); - stop_ = range->EndLayoutObject()->ChildAt(range->EndOffset()); - if (stop_) - return; - stop_ = range->EndLayoutObject()->NextInPreOrderAfterChildren(); } LayoutObject* SelectionPaintRange::Iterator::operator*() const { @@ -94,9 +93,10 @@ SelectionPaintRange::Iterator& SelectionPaintRange::Iterator::operator++() { DCHECK(current_); - for (current_ = current_->NextInPreOrder(); current_ && current_ != stop_; + for (current_ = current_->NextInPreOrder(); + current_ && current_ != range_->traverse_stop_; current_ = current_->NextInPreOrder()) { - if (current_ == included_end_ || current_->CanBeSelectionLeaf()) + if (current_->CanBeSelectionLeaf()) return *this; }
diff --git a/third_party/WebKit/Source/core/editing/LayoutSelection.h b/third_party/WebKit/Source/core/editing/LayoutSelection.h index f56967b..c67ca15 100644 --- a/third_party/WebKit/Source/core/editing/LayoutSelection.h +++ b/third_party/WebKit/Source/core/editing/LayoutSelection.h
@@ -57,9 +57,8 @@ LayoutObject* operator*() const; private: + const SelectionPaintRange* range_; LayoutObject* current_; - const LayoutObject* included_end_; - const LayoutObject* stop_; }; Iterator begin() const { return Iterator(this); }; Iterator end() const { return Iterator(nullptr); }; @@ -84,6 +83,7 @@ int start_offset_ = -1; LayoutObject* end_layout_object_ = nullptr; int end_offset_ = -1; + LayoutObject* traverse_stop_ = nullptr; }; class LayoutSelection final : public GarbageCollected<LayoutSelection> {
diff --git a/third_party/WebKit/Source/core/editing/SelectionController.cpp b/third_party/WebKit/Source/core/editing/SelectionController.cpp index a64208a..eccb5f8 100644 --- a/third_party/WebKit/Source/core/editing/SelectionController.cpp +++ b/third_party/WebKit/Source/core/editing/SelectionController.cpp
@@ -71,6 +71,17 @@ namespace { +SelectionInDOMTree ConvertToSelectionInDOMTree( + const SelectionInFlatTree& selection_in_flat_tree) { + return SelectionInDOMTree::Builder() + .SetAffinity(selection_in_flat_tree.Affinity()) + .SetBaseAndExtent(ToPositionInDOMTree(selection_in_flat_tree.Base()), + ToPositionInDOMTree(selection_in_flat_tree.Extent())) + .SetIsDirectional(selection_in_flat_tree.IsDirectional()) + .SetIsHandleVisible(selection_in_flat_tree.IsHandleVisible()) + .Build(); +} + DispatchEventResult DispatchSelectStart(Node* node) { if (!node || !node->GetLayoutObject()) return DispatchEventResult::kNotCanceled; @@ -786,7 +797,7 @@ Selection().IsHandleVisible() == selection_in_flat_tree.IsHandleVisible()) return; Selection().SetSelection( - selection_in_flat_tree, + ConvertToSelectionInDOMTree(selection_in_flat_tree), FrameSelection::kCloseTyping | FrameSelection::kClearTypingStyle, CursorAlignOnScroll::kIfNeeded, granularity); } @@ -1006,7 +1017,7 @@ if (Selection().ComputeVisibleSelectionInFlatTree() != CreateVisibleSelection(builder.Build())) { - Selection().SetSelection(builder.Build()); + Selection().SetSelection(ConvertToSelectionInDOMTree(builder.Build())); } handled = true; @@ -1164,12 +1175,13 @@ const VisiblePositionInFlatTree& visible_pos = VisiblePositionOfHitTestResult(mev.GetHitTestResult()); if (visible_pos.IsNull()) { - Selection().SetSelection(SelectionInFlatTree()); + Selection().SetSelection(SelectionInDOMTree()); return; } - Selection().SetSelection(SelectionInFlatTree::Builder() - .Collapse(visible_pos.ToPositionWithAffinity()) - .Build()); + Selection().SetSelection(ConvertToSelectionInDOMTree( + SelectionInFlatTree::Builder() + .Collapse(visible_pos.ToPositionWithAffinity()) + .Build())); } void SelectionController::InitializeSelectionState() {
diff --git a/third_party/WebKit/Source/core/editing/VisibleSelection.cpp b/third_party/WebKit/Source/core/editing/VisibleSelection.cpp index a55d7d2..3d291db 100644 --- a/third_party/WebKit/Source/core/editing/VisibleSelection.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleSelection.cpp
@@ -574,6 +574,40 @@ return nullptr; } +// The selection ends in editable content or non-editable content inside a +// different editable ancestor, move backward until non-editable content inside +// the same lowest editable ancestor is reached. +template <typename Strategy> +PositionTemplate<Strategy> AdjustSelectionEndToAvoidCrossingEditingBoundaries( + const PositionTemplate<Strategy>& end, + ContainerNode* end_root, + Element* base_editable_ancestor) { + Element* const end_editable_ancestor = + LowestEditableAncestor(end.ComputeContainerNode()); + if (end_root || end_editable_ancestor != base_editable_ancestor) { + PositionTemplate<Strategy> position = + PreviousVisuallyDistinctCandidate(end); + Element* shadow_ancestor = end_root ? end_root->OwnerShadowHost() : nullptr; + if (position.IsNull() && shadow_ancestor) + position = PositionTemplate<Strategy>::AfterNode(*shadow_ancestor); + while (position.IsNotNull() && + !(LowestEditableAncestor(position.ComputeContainerNode()) == + base_editable_ancestor && + !IsEditablePosition(position))) { + Element* root = RootEditableElementOf(position); + shadow_ancestor = root ? root->OwnerShadowHost() : nullptr; + position = IsAtomicNode(position.ComputeContainerNode()) + ? PositionTemplate<Strategy>::InParentBeforeNode( + *position.ComputeContainerNode()) + : PreviousVisuallyDistinctCandidate(position); + if (position.IsNull() && shadow_ancestor) + position = PositionTemplate<Strategy>::AfterNode(*shadow_ancestor); + } + return CreateVisiblePosition(position).DeepEquivalent(); + } + return end; +} + template <typename Strategy> void VisibleSelectionTemplate< Strategy>::AdjustSelectionToAvoidCrossingEditingBoundaries() { @@ -623,42 +657,14 @@ } else { // FIXME: Non-editable pieces inside editable content should be atomic, in // the same way that editable pieces in non-editable content are atomic. - - // The selection ends in editable content or non-editable content inside a - // different editable ancestor, move backward until non-editable content - // inside the same lowest editable ancestor is reached. - Element* end_editable_ancestor = - LowestEditableAncestor(end_.ComputeContainerNode()); - if (end_root || end_editable_ancestor != base_editable_ancestor) { - PositionTemplate<Strategy> p = PreviousVisuallyDistinctCandidate(end_); - Element* shadow_ancestor = - end_root ? end_root->OwnerShadowHost() : nullptr; - if (p.IsNull() && shadow_ancestor) - p = PositionTemplate<Strategy>::AfterNode(*shadow_ancestor); - while (p.IsNotNull() && - !(LowestEditableAncestor(p.ComputeContainerNode()) == - base_editable_ancestor && - !IsEditablePosition(p))) { - Element* root = RootEditableElementOf(p); - shadow_ancestor = root ? root->OwnerShadowHost() : nullptr; - p = IsAtomicNode(p.ComputeContainerNode()) - ? PositionTemplate<Strategy>::InParentBeforeNode( - *p.ComputeContainerNode()) - : PreviousVisuallyDistinctCandidate(p); - if (p.IsNull() && shadow_ancestor) - p = PositionTemplate<Strategy>::AfterNode(*shadow_ancestor); - } - const VisiblePositionTemplate<Strategy> previous = - CreateVisiblePosition(p); - - if (previous.IsNull()) { - // The selection crosses an Editing boundary. This is a - // programmer error in the editing code. Happy debugging! - NOTREACHED(); - *this = VisibleSelectionTemplate<Strategy>(); - return; - } - end_ = previous.DeepEquivalent(); + end_ = AdjustSelectionEndToAvoidCrossingEditingBoundaries( + end_, end_root, base_editable_ancestor); + if (end_.IsNull()) { + // The selection crosses an Editing boundary. This is a + // programmer error in the editing code. Happy debugging! + NOTREACHED(); + *this = VisibleSelectionTemplate<Strategy>(); + return; } // The selection starts in editable content or non-editable content inside a @@ -697,11 +703,6 @@ start_ = next.DeepEquivalent(); } } - - // Correct the extent if necessary. - if (base_editable_ancestor != - LowestEditableAncestor(extent_.ComputeContainerNode())) - extent_ = base_is_first_ ? end_ : start_; } template <typename Strategy>
diff --git a/third_party/WebKit/Source/core/exported/WebFactory.h b/third_party/WebKit/Source/core/exported/WebFactory.h index 07e6208a..4f0cedf 100644 --- a/third_party/WebKit/Source/core/exported/WebFactory.h +++ b/third_party/WebKit/Source/core/exported/WebFactory.h
@@ -12,6 +12,7 @@ namespace blink { class ChromeClient; +class LocalFrameClient; class WebView; class WebViewBase; class WebLocalFrameBase; @@ -40,6 +41,8 @@ WebFrameClient*, InterfaceRegistry*, WebFrame* opener) const = 0; + virtual LocalFrameClient* CreateLocalFrameClient( + WebLocalFrameBase*) const = 0; protected: // Takes ownership of |factory|.
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameClient.h b/third_party/WebKit/Source/core/frame/LocalFrameClient.h index 402eac4..972ac8c1 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrameClient.h +++ b/third_party/WebKit/Source/core/frame/LocalFrameClient.h
@@ -85,6 +85,7 @@ class WebApplicationCacheHost; class WebApplicationCacheHostClient; class WebCookieJar; +class WebFrame; class WebMediaPlayer; class WebMediaPlayerClient; class WebMediaPlayerSource; @@ -99,6 +100,8 @@ public: ~LocalFrameClient() override {} + virtual WebFrame* GetWebFrame() const { return nullptr; } + virtual bool HasWebView() const = 0; // mainly for assertions virtual void DispatchWillSendRequest(ResourceRequest&) = 0;
diff --git a/third_party/WebKit/Source/devtools/front_end/color_picker/Spectrum.js b/third_party/WebKit/Source/devtools/front_end/color_picker/Spectrum.js index f45965c..0869c213 100644 --- a/third_party/WebKit/Source/devtools/front_end/color_picker/Spectrum.js +++ b/third_party/WebKit/Source/devtools/front_end/color_picker/Spectrum.js
@@ -115,7 +115,7 @@ UI.installDragHandle( this._colorElement, dragStart.bind(this, positionColor.bind(this)), positionColor.bind(this), null, 'default'); - this.element.classList.add('palettes-enabled'); + this.element.classList.add('palettes-enabled', 'flex-none'); /** @type {!Map.<string, !ColorPicker.Spectrum.Palette>} */ this._palettes = new Map(); this._palettePanel = this.contentElement.createChild('div', 'palette-panel');
diff --git a/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js b/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js index a0d3ec7..67db0c4 100644 --- a/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js +++ b/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js
@@ -204,7 +204,12 @@ break; case ConsoleModel.ConsoleMessage.MessageType.Clear: messageElement = createElementWithClass('span', 'console-info'); - messageElement.textContent = Common.UIString('Console was cleared'); + if (Common.moduleSetting('preserveConsoleLog').get()) + messageElement.textContent = Common.UIString('console.clear() was prevented due to \'Preserve log\''); + else + messageElement.textContent = Common.UIString('Console was cleared'); + messageElement.title = + Common.UIString('Clear all messages with ' + UI.shortcutRegistry.shortcutTitleForAction('console.clear')); break; case ConsoleModel.ConsoleMessage.MessageType.Assert: var args = [Common.UIString('Assertion failed:')];
diff --git a/third_party/WebKit/Source/devtools/front_end/console_model/ConsoleModel.js b/third_party/WebKit/Source/devtools/front_end/console_model/ConsoleModel.js index ad35836..d79b3503 100644 --- a/third_party/WebKit/Source/devtools/front_end/console_model/ConsoleModel.js +++ b/third_party/WebKit/Source/devtools/front_end/console_model/ConsoleModel.js
@@ -162,7 +162,7 @@ if (msg.source === ConsoleModel.ConsoleMessage.MessageSource.ConsoleAPI && msg.type === ConsoleModel.ConsoleMessage.MessageType.Clear) - this._clear(); + this._clearIfNecessary(); this._messages.push(msg); var runtimeModel = msg.runtimeModel(); @@ -250,10 +250,7 @@ this.addMessage(consoleMessage); } - /** - * @param {!Common.Event} event - */ - _clearIfNecessary(event) { + _clearIfNecessary() { if (!Common.moduleSetting('preserveConsoleLog').get()) this._clear(); }
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/GlassPane.js b/third_party/WebKit/Source/devtools/front_end/ui/GlassPane.js index 9375cb0..dd6f964f 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/GlassPane.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/GlassPane.js
@@ -159,7 +159,7 @@ var showArrow = this._marginBehavior === UI.GlassPane.MarginBehavior.Arrow; var gutterSize = showArrow ? 8 : (this._marginBehavior === UI.GlassPane.MarginBehavior.NoMargin ? 0 : 3); - var scrollbarSize = 14; + var scrollbarSize = 15; var arrowSize = 10; var container = UI.GlassPane._containers.get(/** @type {!Document} */ (this.element.ownerDocument));
diff --git a/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp b/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp index cac5d29..a182100 100644 --- a/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp +++ b/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp
@@ -164,6 +164,10 @@ LocalFrameClient::Trace(visitor); } +WebLocalFrameBase* LocalFrameClientImpl::GetWebFrame() const { + return web_frame_.Get(); +} + void LocalFrameClientImpl::DidCreateNewDocument() { if (web_frame_->Client()) web_frame_->Client()->DidCreateNewDocument(web_frame_);
diff --git a/third_party/WebKit/Source/web/LocalFrameClientImpl.h b/third_party/WebKit/Source/web/LocalFrameClientImpl.h index c02c52d3..f904502 100644 --- a/third_party/WebKit/Source/web/LocalFrameClientImpl.h +++ b/third_party/WebKit/Source/web/LocalFrameClientImpl.h
@@ -33,6 +33,7 @@ #define LocalFrameClientImpl_h #include "core/frame/LocalFrameClient.h" +#include "core/frame/WebLocalFrameBase.h" #include "platform/heap/Handle.h" #include "platform/weborigin/KURL.h" #include "platform/wtf/RefPtr.h" @@ -54,7 +55,7 @@ DECLARE_VIRTUAL_TRACE(); - WebLocalFrameBase* GetWebFrame() const { return web_frame_.Get(); } + WebLocalFrameBase* GetWebFrame() const override; // LocalFrameClient ----------------------------------------------
diff --git a/third_party/WebKit/Source/web/WebFactoryImpl.cpp b/third_party/WebKit/Source/web/WebFactoryImpl.cpp index 45d9449..3633d2dc 100644 --- a/third_party/WebKit/Source/web/WebFactoryImpl.cpp +++ b/third_party/WebKit/Source/web/WebFactoryImpl.cpp
@@ -4,6 +4,7 @@ #include "web/WebFactoryImpl.h" #include "web/ChromeClientImpl.h" +#include "web/LocalFrameClientImpl.h" #include "web/WebLocalFrameImpl.h" #include "web/WebViewImpl.h" @@ -40,4 +41,9 @@ return WebLocalFrameImpl::Create(type, client, registry, opener); } +LocalFrameClient* WebFactoryImpl::CreateLocalFrameClient( + WebLocalFrameBase* local_frame_base) const { + return LocalFrameClientImpl::Create(local_frame_base); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/web/WebFactoryImpl.h b/third_party/WebKit/Source/web/WebFactoryImpl.h index 9219769..259214b 100644 --- a/third_party/WebKit/Source/web/WebFactoryImpl.h +++ b/third_party/WebKit/Source/web/WebFactoryImpl.h
@@ -29,6 +29,8 @@ WebFrameClient*, InterfaceRegistry*, WebFrame* opener) const override; + + LocalFrameClient* CreateLocalFrameClient(WebLocalFrameBase*) const override; }; } // namespace blink
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp index 355d863..9703a28 100644 --- a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp +++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
@@ -127,6 +127,7 @@ #include "core/exported/WebAssociatedURLLoaderImpl.h" #include "core/exported/WebDataSourceImpl.h" #include "core/exported/WebDevToolsAgentImpl.h" +#include "core/exported/WebFactory.h" #include "core/exported/WebPluginContainerImpl.h" #include "core/exported/WebRemoteFrameImpl.h" #include "core/exported/WebViewBase.h" @@ -1597,7 +1598,8 @@ WebFrameClient* client, blink::InterfaceRegistry* interface_registry) : WebLocalFrameBase(scope), - local_frame_client_impl_(LocalFrameClientImpl::Create(this)), + local_frame_client_( + WebFactory::GetInstance().CreateLocalFrameClient(this)), client_(client), autofill_client_(0), input_events_scale_factor_for_emulation_(1), @@ -1629,7 +1631,7 @@ } DEFINE_TRACE(WebLocalFrameImpl) { - visitor->Trace(local_frame_client_impl_); + visitor->Trace(local_frame_client_); visitor->Trace(frame_); visitor->Trace(dev_tools_agent_); visitor->Trace(frame_widget_); @@ -1650,7 +1652,7 @@ void WebLocalFrameImpl::InitializeCoreFrame(Page& page, FrameOwner* owner, const AtomicString& name) { - SetCoreFrame(LocalFrame::Create(local_frame_client_impl_.Get(), page, owner, + SetCoreFrame(LocalFrame::Create(local_frame_client_.Get(), page, owner, interface_registry_)); frame_->Tree().SetName(name); // We must call init() after frame_ is assigned because it is referenced @@ -1756,7 +1758,7 @@ LocalFrameClient* client = frame.Client(); if (!client || !client->IsLocalFrameClientImpl()) return nullptr; - return ToWebLocalFrameImpl(ToLocalFrameClientImpl(client)->GetWebFrame()); + return ToWebLocalFrameImpl(client->GetWebFrame()); } WebLocalFrameImpl* WebLocalFrameImpl::FromFrameOwnerElement(Element* element) {
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.h b/third_party/WebKit/Source/web/WebLocalFrameImpl.h index 4695423..ccc34a8 100644 --- a/third_party/WebKit/Source/web/WebLocalFrameImpl.h +++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.h
@@ -37,14 +37,12 @@ #include "core/frame/LocalFrame.h" #include "core/frame/WebFrameWidgetBase.h" #include "core/frame/WebLocalFrameBase.h" -#include "modules/mediastream/UserMediaClientImpl.h" #include "platform/geometry/FloatRect.h" #include "platform/heap/SelfKeepAlive.h" #include "platform/wtf/Compiler.h" #include "platform/wtf/text/WTFString.h" #include "public/platform/WebFileSystemType.h" #include "public/web/WebLocalFrame.h" -#include "web/LocalFrameClientImpl.h" #include "web/WebExport.h" #include <memory> @@ -54,6 +52,7 @@ class ChromePrintContext; class IntSize; class KURL; +class LocalFrameClient; class ScrollableArea; class SharedWorkerRepositoryClientImpl; class TextCheckerClient; @@ -450,7 +449,6 @@ DECLARE_VIRTUAL_TRACE(); private: - friend class LocalFrameClientImpl; WebLocalFrameImpl(WebTreeScopeType, WebFrameClient*, @@ -479,7 +477,7 @@ // Returns true if the frame is focused. bool IsFocused() const; - Member<LocalFrameClientImpl> local_frame_client_impl_; + Member<LocalFrameClient> local_frame_client_; // The embedder retains a reference to the WebCore LocalFrame while it is // active in the DOM. This reference is released when the frame is removed
diff --git a/tools/gn/bootstrap/bootstrap.py b/tools/gn/bootstrap/bootstrap.py index 8beca90..231ff03 100755 --- a/tools/gn/bootstrap/bootstrap.py +++ b/tools/gn/bootstrap/bootstrap.py
@@ -467,7 +467,6 @@ 'base/process/process_metrics.cc', 'base/profiler/scoped_profile.cc', 'base/profiler/scoped_tracker.cc', - 'base/profiler/tracked_time.cc', 'base/rand_util.cc', 'base/run_loop.cc', 'base/sequence_token.cc', @@ -567,6 +566,7 @@ 'base/tracked_objects.cc', 'base/tracking_info.cc', 'base/unguessable_token.cc', + 'base/value_iterators.cc', 'base/values.cc', 'base/vlog.cc', ])
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 20cfee2..4eed89e2 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -15536,6 +15536,74 @@ </description> </action> +<action name="Signin_ImpressionWithAccount_FromBookmarkManager"> + <owner>jlebel@chromium.org</owner> + <description> + Recorded when starting sign-in using the promo view, with a default account, + from bookmarks manager + (signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER). + </description> +</action> + +<action name="Signin_ImpressionWithAccount_FromRecentTabs"> + <owner>jlebel@chromium.org</owner> + <description> + Recorded when starting sign-in using the promo view, with a default account, + from recent tabs (signin_metrics::AccessPoint::ACCESS_POINT_RECENT_TABS). + </description> +</action> + +<action name="Signin_ImpressionWithAccount_FromSettings"> + <owner>jlebel@chromium.org</owner> + <description> + Recorded when starting sign-in using the promo view, with a default account, + from settings (signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS). + </description> +</action> + +<action name="Signin_ImpressionWithAccount_FromTabSwitcher"> + <owner>jlebel@chromium.org</owner> + <description> + Recorded when starting sign-in using the promo view, with a default account, + from tab switcher (signin_metrics::AccessPoint::ACCESS_POINT_TAB_SWITCHER). + </description> +</action> + +<action name="Signin_ImpressionWithNoAccount_FromBookmarkManager"> + <owner>jlebel@chromium.org</owner> + <description> + Recorded when starting sign-in using the promo view, with no default + account, from bookmarks manager + (signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER). + </description> +</action> + +<action name="Signin_ImpressionWithNoAccount_FromRecentTabs"> + <owner>jlebel@chromium.org</owner> + <description> + Recorded when starting sign-in using the promo view, with no default + account, from recent tabs + (signin_metrics::AccessPoint::ACCESS_POINT_RECENT_TABS). + </description> +</action> + +<action name="Signin_ImpressionWithNoAccount_FromSettings"> + <owner>jlebel@chromium.org</owner> + <description> + Recorded when starting sign-in using the promo view, with no default + account, from settings (signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS). + </description> +</action> + +<action name="Signin_ImpressionWithNoAccount_FromTabSwitcher"> + <owner>jlebel@chromium.org</owner> + <description> + Recorded when starting sign-in using the promo view, with no default + account, from tab switcher + (signin_metrics::AccessPoint::ACCESS_POINT_TAB_SWITCHER). + </description> +</action> + <action name="Signin_Impression_FromAppsPageLink"> <owner>gogerald@chromium.org</owner> <description>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 7e86cf5..d80500cc 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -9256,6 +9256,21 @@ <int value="9" label="SCRIPT_READ_FINISHED"/> </enum> +<enum name="EmmcLifeUsed"> + <int value="0" label="Not defined"/> + <int value="1" label="0% - 10% device life time used"/> + <int value="2" label="10% -20% device life time used"/> + <int value="3" label="20% -30% device life time used"/> + <int value="4" label="30% - 40% device life time used"/> + <int value="5" label="40% - 50% device life time used"/> + <int value="6" label="50% - 60% device life time used"/> + <int value="7" label="60% - 70% device life time used"/> + <int value="8" label="70% - 80% device life time used"/> + <int value="9" label="80% - 90% device life time used"/> + <int value="10" label="90% - 100% device life time used"/> + <int value="11" label="Exceeded its maximum estimated device life time"/> +</enum> + <enum name="EncodingMethod"> <int value="0" label="UNKNOWN"/> <int value="1" label="Big5"/> @@ -22645,6 +22660,7 @@ <int value="-1812579951" label="ContentSuggestionsCategoryRanker:enabled"/> <int value="-1811394154" label="disable-webrtc-hw-vp8-encoding"/> <int value="-1810294310" label="AndroidPaymentApps:enabled"/> + <int value="-1808477331" label="MidiManagerCros:disabled"/> <int value="-1804485171" label="disable-fullscreen-tab-detaching"/> <int value="-1802502753" label="enable-manual-password-generation:enabled"/> <int value="-1798337879" label="enable-md-downloads"/> @@ -23107,6 +23123,7 @@ <int value="-216219963" label="ash-shelf-color-scheme"/> <int value="-213518852" label="protect-sync-credential:enabled"/> <int value="-213214894" label="enable-chromevox-arc-support"/> + <int value="-208435024" label="EnableUsernameCorrection:enabled"/> <int value="-206393363" label="enable-scroll-prediction"/> <int value="-204355195" label="secondary-ui-md"/> <int value="-202007318" label="AndroidAIAFetching:enabled"/> @@ -23345,6 +23362,7 @@ <int value="644674603" label="DataReductionProxySiteBreakdown:disabled"/> <int value="646252875" label="ReadItLaterInMenu:enabled"/> <int value="646738320" label="disable-gesture-editing"/> + <int value="649111851" label="MidiManagerCros:enabled"/> <int value="651421878" label="VideoRotateToFullscreen:enabled"/> <int value="652561231" label="CustomContextMenu:enabled"/> <int value="683410401" @@ -23762,6 +23780,7 @@ <int value="2014331873" label="NTPDownloadSuggestions:disabled"/> <int value="2020107447" label="AndroidPayIntegrationV1:enabled"/> <int value="2037756154" label="enable-impl-side-painting"/> + <int value="2056572020" label="EnableUsernameCorrection:disabled"/> <int value="2059322877" label="new-avatar-menu"/> <int value="2063091429" label="OfflinePagesSharing:enabled"/> <int value="2067634730" label="LsdPermissionPrompt:disabled"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 0e249e8..3a75eab 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -54666,6 +54666,16 @@ </summary> </histogram> +<histogram name="Platform.Emmc.LifeUsed" enum="EmmcLifeUsed"> + <owner>gwendal@google.com</owner> + <summary> + eMMC [5.0] Device life time estimation for flash. This field provides an + estimated indication about the device life time that is reflected by the + averaged wear out of memory of a given type relative to its maximum + estimated lifetime. + </summary> +</histogram> + <histogram name="Platform.IntelMaxMicroArchitecture" enum="IntelMaxMicroArchitecture"> <owner>fbarchard@chromium.org</owner> @@ -96295,6 +96305,12 @@ <affected-histogram name="Platform.BootMode.FirmwareWriteProtect"/> </histogram_suffixes> +<histogram_suffixes name="PlatformEmmcLifeUsed" separator="."> + <suffix name="TypeA" label="Memory Type A"/> + <suffix name="TypeB" label="Memory Type B"/> + <affected-histogram name="Platform.Emmc.LifeUsed"/> +</histogram_suffixes> + <histogram_suffixes name="PlatformMeminfoPercentage" separator=""> <suffix name="infoActive" label="Active memory."/> <suffix name="infoActiveAnon"
diff --git a/ui/aura/mus/input_method_mus_unittest.cc b/ui/aura/mus/input_method_mus_unittest.cc index 51ed8279..e430f57 100644 --- a/ui/aura/mus/input_method_mus_unittest.cc +++ b/ui/aura/mus/input_method_mus_unittest.cc
@@ -4,6 +4,8 @@ #include "ui/aura/mus/input_method_mus.h" +#include <utility> + #include "services/ui/public/interfaces/ime/ime.mojom.h" #include "ui/aura/test/aura_test_base.h" #include "ui/aura/test/mus/input_method_mus_test_api.h" @@ -29,7 +31,7 @@ DISALLOW_COPY_AND_ASSIGN(TestInputMethodDelegate); }; -using ProcessKeyEventCallback = base::Callback<void(bool)>; +using ProcessKeyEventCallback = base::OnceCallback<void(bool)>; using ProcessKeyEventCallbacks = std::vector<ProcessKeyEventCallback>; using EventResultCallback = base::Callback<void(ui::mojom::EventResult)>; @@ -48,8 +50,8 @@ void OnTextInputTypeChanged(ui::TextInputType text_input_type) override {} void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override {} void ProcessKeyEvent(std::unique_ptr<ui::Event> key_event, - const ProcessKeyEventCallback& callback) override { - process_key_event_callbacks_.push_back(callback); + ProcessKeyEventCallback callback) override { + process_key_event_callbacks_.push_back(std::move(callback)); } void CancelComposition() override {} @@ -197,7 +199,7 @@ ASSERT_EQ(1u, test_input_method.process_key_event_callbacks()->size()); // Callback should not have been run yet. EXPECT_FALSE(was_event_result_callback_run); - (*test_input_method.process_key_event_callbacks())[0].Run(false); + std::move((*test_input_method.process_key_event_callbacks())[0]).Run(false); // Callback should have been run. EXPECT_TRUE(was_event_result_callback_run);
diff --git a/ui/base/ime/input_method_chromeos.cc b/ui/base/ime/input_method_chromeos.cc index de201a3..1312ba4 100644 --- a/ui/base/ime/input_method_chromeos.cc +++ b/ui/base/ime/input_method_chromeos.cc
@@ -9,6 +9,7 @@ #include <algorithm> #include <cstring> #include <set> +#include <utility> #include <vector> #include "base/bind.h"
diff --git a/ui/file_manager/file_manager/foreground/js/gear_menu_controller.js b/ui/file_manager/file_manager/foreground/js/gear_menu_controller.js index b035356..28e65d0 100644 --- a/ui/file_manager/file_manager/foreground/js/gear_menu_controller.js +++ b/ui/file_manager/file_manager/foreground/js/gear_menu_controller.js
@@ -41,6 +41,8 @@ */ this.commandHandler_ = commandHandler; + gearMenu.volumeSpaceInfo.addEventListener( + 'mouseover', this.onMouseOverVolumeSpaceInfo_.bind(this)); gearButton.addEventListener('menushow', this.onShowGearMenu_.bind(this)); gearButton.addEventListener('menuhide', this.onHideGearMenu_.bind(this)); directoryModel.addEventListener( @@ -51,6 +53,15 @@ } /** + * Handles mouseover event and prevents any further action to execute. + * @param {Event} event The mouseover event. + * @private + */ +GearMenuController.prototype.onMouseOverVolumeSpaceInfo_ = function(event) { + event.stopPropagation(); +}; + +/** * @private */ GearMenuController.prototype.onShowGearMenu_ = function() {
diff --git a/ui/file_manager/file_manager/foreground/js/ui/gear_menu.js b/ui/file_manager/file_manager/foreground/js/ui/gear_menu.js index 8807c5c..28bfe1bb 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/gear_menu.js +++ b/ui/file_manager/file_manager/foreground/js/ui/gear_menu.js
@@ -25,9 +25,8 @@ /** * @type {!HTMLElement} * @const - * @private */ - this.volumeSpaceInfo_ = queryRequiredElement('#volume-space-info', element); + this.volumeSpaceInfo = queryRequiredElement('#volume-space-info', element); /** * @type {!HTMLElement} @@ -84,12 +83,12 @@ this.spaceInfoPromise_ = spaceInfoPromise; if (!spaceInfoPromise) { - this.volumeSpaceInfo_.hidden = true; + this.volumeSpaceInfo.hidden = true; this.volumeSpaceInfoSeparator_.hidden = true; return; } - this.volumeSpaceInfo_.hidden = false; + this.volumeSpaceInfo.hidden = false; this.volumeSpaceInfoSeparator_.hidden = false; this.volumeSpaceInnerBar_.setAttribute('pending', ''); if (showLoadingCaption) {