| // Copyright 2019 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/ui/webui/ash/sync/os_sync_handler.h" |
| |
| #include "base/auto_reset.h" |
| #include "base/bind.h" |
| #include "base/check_op.h" |
| #include "base/values.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/sync/sync_service_factory.h" |
| #include "chrome/browser/ui/webui/settings/ash/pref_names.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/sync/base/pref_names.h" |
| #include "components/sync/base/user_selectable_type.h" |
| #include "components/sync/driver/sync_service.h" |
| #include "components/sync/driver/sync_user_settings.h" |
| #include "content/public/browser/web_ui.h" |
| |
| using syncer::SyncService; |
| using syncer::SyncUserSettings; |
| using syncer::UserSelectableOsType; |
| using syncer::UserSelectableOsTypeSet; |
| |
| namespace ash { |
| |
| namespace { |
| const char kWallpaperEnabledKey[] = "wallpaperEnabled"; |
| } // namespace |
| |
| OSSyncHandler::OSSyncHandler(Profile* profile) : profile_(profile) { |
| DCHECK(profile_); |
| } |
| |
| OSSyncHandler::~OSSyncHandler() { |
| RemoveSyncServiceObserver(); |
| } |
| |
| void OSSyncHandler::RegisterMessages() { |
| web_ui()->RegisterMessageCallback( |
| "DidNavigateToOsSyncPage", |
| base::BindRepeating(&OSSyncHandler::HandleDidNavigateToOsSyncPage, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback( |
| "DidNavigateAwayFromOsSyncPage", |
| base::BindRepeating(&OSSyncHandler::HandleDidNavigateAwayFromOsSyncPage, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback( |
| "OsSyncPrefsDispatch", |
| base::BindRepeating(&OSSyncHandler::HandleOsSyncPrefsDispatch, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback( |
| "SetOsSyncDatatypes", |
| base::BindRepeating(&OSSyncHandler::HandleSetOsSyncDatatypes, |
| base::Unretained(this))); |
| } |
| |
| void OSSyncHandler::OnJavascriptAllowed() { |
| AddSyncServiceObserver(); |
| } |
| |
| void OSSyncHandler::OnJavascriptDisallowed() { |
| RemoveSyncServiceObserver(); |
| } |
| |
| void OSSyncHandler::OnStateChanged(syncer::SyncService* service) { |
| PushSyncPrefs(); |
| } |
| |
| void OSSyncHandler::HandleDidNavigateToOsSyncPage( |
| const base::Value::List& args) { |
| HandleOsSyncPrefsDispatch(args); |
| } |
| |
| void OSSyncHandler::HandleOsSyncPrefsDispatch(const base::Value::List& args) { |
| AllowJavascript(); |
| |
| PushSyncPrefs(); |
| } |
| |
| void OSSyncHandler::HandleDidNavigateAwayFromOsSyncPage( |
| const base::Value::List& args) { |
| // TODO(https://crbug.com/1278325): Remove this. |
| } |
| |
| void OSSyncHandler::HandleSetOsSyncDatatypes(const base::Value::List& args) { |
| CHECK_EQ(1u, args.size()); |
| const base::Value& result_value = args[0]; |
| CHECK(result_value.is_dict()); |
| const base::Value::Dict& result = result_value.GetDict(); |
| |
| // Wallpaper sync status is stored directly to the profile's prefs. |
| bool wallpaper_synced = result.FindBool(kWallpaperEnabledKey).value(); |
| profile_->GetPrefs()->SetBoolean(settings::prefs::kSyncOsWallpaper, |
| wallpaper_synced); |
| |
| // Start configuring the SyncService using the configuration passed to us from |
| // the JS layer. |
| syncer::SyncService* service = GetSyncService(); |
| |
| // If the sync engine has shutdown for some reason, just stop. |
| if (!service || !service->IsEngineInitialized()) |
| return; |
| |
| bool sync_all_os_types = result.FindBool("syncAllOsTypes").value(); |
| |
| UserSelectableOsTypeSet selected_types; |
| for (UserSelectableOsType type : UserSelectableOsTypeSet::All()) { |
| std::string key = |
| syncer::GetUserSelectableOsTypeName(type) + std::string("Synced"); |
| absl::optional<bool> sync_value = result.FindBool(key); |
| CHECK(sync_value.has_value()) << key; |
| if (sync_value.value()) |
| selected_types.Put(type); |
| } |
| |
| // Filter out any non-registered types. The WebUI may echo back values from |
| // toggles for in-development features hidden by feature flags. |
| SyncUserSettings* settings = service->GetUserSettings(); |
| selected_types.RetainAll(settings->GetRegisteredSelectableOsTypes()); |
| |
| settings->SetSelectedOsTypes(sync_all_os_types, selected_types); |
| |
| // TODO(jamescook): Add metrics for selected types. |
| } |
| |
| void OSSyncHandler::SetWebUIForTest(content::WebUI* web_ui) { |
| set_web_ui(web_ui); |
| } |
| |
| void OSSyncHandler::PushSyncPrefs() { |
| syncer::SyncService* service = GetSyncService(); |
| // The sync service may be nullptr if it has been just disabled by policy. |
| if (!service || !service->IsEngineInitialized()) |
| return; |
| |
| base::Value::Dict args; |
| SyncUserSettings* user_settings = service->GetUserSettings(); |
| // Tell the UI layer which data types are registered/enabled by the user. |
| args.Set("syncAllOsTypes", user_settings->IsSyncAllOsTypesEnabled()); |
| UserSelectableOsTypeSet registered_types = |
| user_settings->GetRegisteredSelectableOsTypes(); |
| UserSelectableOsTypeSet selected_types = user_settings->GetSelectedOsTypes(); |
| |
| for (UserSelectableOsType type : UserSelectableOsTypeSet::All()) { |
| std::string type_name = syncer::GetUserSelectableOsTypeName(type); |
| args.SetByDottedPath(type_name + "Registered", registered_types.Has(type)); |
| args.SetByDottedPath(type_name + "Synced", selected_types.Has(type)); |
| } |
| |
| // Wallpaper sync status is fetched from prefs and is considered enabled if |
| // all OS types are enabled; this mimics behavior of GetSelectedOsTypes(). |
| args.Set(kWallpaperEnabledKey, user_settings->IsSyncAllOsTypesEnabled() || |
| profile_->GetPrefs()->GetBoolean( |
| settings::prefs::kSyncOsWallpaper)); |
| |
| FireWebUIListener("os-sync-prefs-changed", args); |
| } |
| |
| syncer::SyncService* OSSyncHandler::GetSyncService() const { |
| const bool is_sync_allowed = SyncServiceFactory::IsSyncAllowed(profile_); |
| return is_sync_allowed ? SyncServiceFactory::GetForProfile(profile_) |
| : nullptr; |
| } |
| |
| void OSSyncHandler::AddSyncServiceObserver() { |
| // Observe even if sync isn't allowed. IsSyncAllowed() can change mid-session. |
| SyncService* service = SyncServiceFactory::GetForProfile(profile_); |
| if (service) |
| service->AddObserver(this); |
| } |
| |
| void OSSyncHandler::RemoveSyncServiceObserver() { |
| SyncService* service = SyncServiceFactory::GetForProfile(profile_); |
| if (service) |
| service->RemoveObserver(this); |
| } |
| |
| } // namespace ash |