| // Copyright 2018 The Chromium Authors | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "chrome/browser/ash/policy/display/display_settings_handler.h" | 
 |  | 
 | #include <utility> | 
 |  | 
 | #include "ash/public/ash_interfaces.h" | 
 | #include "base/functional/bind.h" | 
 | #include "base/functional/callback_helpers.h" | 
 | #include "base/location.h" | 
 | #include "base/memory/ref_counted.h" | 
 | #include "base/strings/string_number_conversions.h" | 
 | #include "base/task/single_thread_task_runner.h" | 
 | #include "chromeos/ash/components/settings/cros_settings_names.h" | 
 | #include "mojo/public/cpp/bindings/pending_associated_remote.h" | 
 |  | 
 | namespace policy { | 
 |  | 
 | DisplaySettingsHandler::DisplaySettingsHandler() { | 
 |   ash::BindCrosDisplayConfigController( | 
 |       cros_display_config_.BindNewPipeAndPassReceiver()); | 
 | } | 
 |  | 
 | DisplaySettingsHandler::~DisplaySettingsHandler() = default; | 
 |  | 
 | void DisplaySettingsHandler::OnDisplayConfigChanged() { | 
 |   RequestDisplaysAndApplyChanges(); | 
 | } | 
 |  | 
 | void DisplaySettingsHandler::RegisterHandler( | 
 |     std::unique_ptr<DisplaySettingsPolicyHandler> handler) { | 
 |   if (!started_) | 
 |     handlers_.push_back(std::move(handler)); | 
 | } | 
 |  | 
 | void DisplaySettingsHandler::Start() { | 
 |   if (started_) | 
 |     return; | 
 |   started_ = true; | 
 |  | 
 |   // Register observers for all settings | 
 |   for (const auto& handler : handlers_) { | 
 |     settings_subscriptions_.push_back( | 
 |         ash::CrosSettings::Get()->AddSettingsObserver( | 
 |             handler->SettingName(), | 
 |             base::BindRepeating(&DisplaySettingsHandler::OnSettingUpdate, | 
 |                                 base::Unretained(this), | 
 |                                 base::Unretained(handler.get())))); | 
 |   } | 
 |  | 
 |   // Make the initial display unit info request. This will be queued until the | 
 |   // Ash service is ready. | 
 |   cros_display_config_->GetDisplayUnitInfoList( | 
 |       false /* single_unified */, | 
 |       base::BindOnce(&DisplaySettingsHandler::OnGetInitialDisplayInfo, | 
 |                      weak_ptr_factory_.GetWeakPtr())); | 
 | } | 
 |  | 
 | void DisplaySettingsHandler::OnGetInitialDisplayInfo( | 
 |     std::vector<crosapi::mojom::DisplayUnitInfoPtr> info_list) { | 
 |   // Add this as an observer to the mojo service now that it is ready. | 
 |   // (We only care about changes that occur after we apply any changes below). | 
 |   mojo::PendingAssociatedRemote<crosapi::mojom::CrosDisplayConfigObserver> | 
 |       observer; | 
 |   cros_display_config_observer_receiver_.Bind( | 
 |       observer.InitWithNewEndpointAndPassReceiver()); | 
 |   cros_display_config_->AddObserver(std::move(observer)); | 
 |  | 
 |   ApplyChanges(std::move(info_list)); | 
 | } | 
 |  | 
 | void DisplaySettingsHandler::RequestDisplaysAndApplyChanges() { | 
 |   cros_display_config_->GetDisplayUnitInfoList( | 
 |       false /* single_unified */, | 
 |       base::BindOnce(&DisplaySettingsHandler::ApplyChanges, | 
 |                      weak_ptr_factory_.GetWeakPtr())); | 
 | } | 
 |  | 
 | void DisplaySettingsHandler::ApplyChanges( | 
 |     std::vector<crosapi::mojom::DisplayUnitInfoPtr> info_list) { | 
 |   for (std::unique_ptr<DisplaySettingsPolicyHandler>& handler : handlers_) | 
 |     UpdateSettingAndApplyChanges(handler.get(), info_list); | 
 | } | 
 |  | 
 | void DisplaySettingsHandler::OnSettingUpdate( | 
 |     DisplaySettingsPolicyHandler* handler) { | 
 |   cros_display_config_->GetDisplayUnitInfoList( | 
 |       false /* single_unified */, | 
 |       base::BindOnce(&DisplaySettingsHandler::OnConfigurationChangeForHandler, | 
 |                      weak_ptr_factory_.GetWeakPtr(), handler)); | 
 | } | 
 |  | 
 | void DisplaySettingsHandler::UpdateSettingAndApplyChanges( | 
 |     DisplaySettingsPolicyHandler* handler, | 
 |     const std::vector<crosapi::mojom::DisplayUnitInfoPtr>& info_list) { | 
 |   handler->OnSettingUpdate(); | 
 |   handler->ApplyChanges(cros_display_config_.get(), info_list); | 
 | } | 
 |  | 
 | void DisplaySettingsHandler::OnConfigurationChangeForHandler( | 
 |     DisplaySettingsPolicyHandler* handler, | 
 |     std::vector<crosapi::mojom::DisplayUnitInfoPtr> info_list) { | 
 |   UpdateSettingAndApplyChanges(handler, info_list); | 
 | } | 
 |  | 
 | }  // namespace policy |