// 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/ui/webui/ash/settings/pages/multidevice/multidevice_handler.h"
#include "ash/constants/ash_features.h"
#include "ash/constants/ash_pref_names.h"
#include "ash/public/cpp/new_window_delegate.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/values.h"
#include "chrome/browser/ash/login/quick_unlock/auth_token.h"
#include "chrome/browser/ash/login/quick_unlock/quick_unlock_factory.h"
#include "chrome/browser/ash/login/quick_unlock/quick_unlock_storage.h"
#include "chrome/browser/ash/phonehub/browser_tabs_model_provider_impl.h"
#include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h"
#include "chrome/browser/nearby_sharing/nearby_share_feature_status.h"
#include "chrome/browser/nearby_sharing/nearby_sharing_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/ash/session/session_controller_client_impl.h"
#include "chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_dialog.h"
#include "chromeos/ash/components/multidevice/logging/logging.h"
#include "chromeos/ash/components/osauth/public/auth_session_storage.h"
#include "chromeos/ash/components/phonehub/browser_tabs_model_provider.h"
#include "chromeos/ash/components/phonehub/pref_names.h"
#include "chromeos/ash/components/phonehub/screen_lock_manager.h"
#include "chromeos/ash/components/phonehub/util/histogram_util.h"
#include "chromeos/ash/services/multidevice_setup/public/cpp/prefs.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_message_handler.h"
namespace ash::settings {
using phonehub::util::LogPermissionOnboardingDialogAction;
using phonehub::util::LogPermissionOnboardingSettingsClicked;
using phonehub::util::LogPermissionOnboardingSetupMode;
using phonehub::util::LogPermissionOnboardingSetupResult;
using phonehub::util::PermissionsOnboardingScreenEvent;
using phonehub::util::PermissionsOnboardingSetUpMode;
using phonehub::util::PermissionsOnboardingStep;
namespace {
const char kCameraRollAccessStatus[] = "cameraRollAccessStatus";
const char kPageContentDataModeKey[] = "mode";
const char kPageContentDataHostDeviceNameKey[] = "hostDeviceName";
const char kPageContentDataBetterTogetherStateKey[] = "betterTogetherState";
const char kPageContentDataInstantTetheringStateKey[] = "instantTetheringState";
const char kPageContentDataPhoneHubStateKey[] = "phoneHubState";
const char kPageContentDataPhoneHubCameraRollStateKey[] =
"phoneHubCameraRollState";
const char kPageContentDataPhoneHubNotificationsStateKey[] =
"phoneHubNotificationsState";
const char kPageContentDataPhoneHubTaskContinuationStateKey[] =
"phoneHubTaskContinuationState";
const char kPageContentDataPhoneHubAppsStateKey[] = "phoneHubAppsState";
const char kPageContentDataWifiSyncStateKey[] = "wifiSyncState";
const char kPageContentDataSmartLockStateKey[] = "smartLockState";
const char kNotificationAccessStatus[] = "notificationAccessStatus";
const char kNotificationAccessProhibitedReason[] =
"notificationAccessProhibitedReason";
const char kIsNearbyShareDisallowedByPolicy[] =
"isNearbyShareDisallowedByPolicy";
const char kAppsAccessStatus[] = "appsAccessStatus";
const char kIsPhoneHubPermissionsDialogSupported[] =
"isPhoneHubPermissionsDialogSupported";
const char kIsCameraRollFilePermissionGranted[] =
"isCameraRollFilePermissionGranted";
const char kIsPhoneHubFeatureCombinedSetupSupported[] =
"isPhoneHubFeatureCombinedSetupSupported";
const char kIsChromeOSSyncedSessionSharingEnabled[] =
"isChromeOSSyncedSessionSharingEnabled";
const char kIsLacrosTabSyncEnabled[] = "isLacrosTabSyncEnabled";
void OnRetrySetHostNowResult(bool success) {
if (success) {
return;
}
PA_LOG(WARNING) << "OnRetrySetHostNowResult(): Attempt to retry setting the "
<< "host device failed.";
}
} // namespace
MultideviceHandler::MultideviceHandler(
PrefService* prefs,
multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
phonehub::MultideviceFeatureAccessManager*
multidevice_feature_access_manager,
eche_app::AppsAccessManager* apps_access_manager,
phonehub::CameraRollManager* camera_roll_manager,
phonehub::BrowserTabsModelProvider* browser_tabs_model_provider)
: prefs_(prefs),
multidevice_setup_client_(multidevice_setup_client),
multidevice_feature_access_manager_(multidevice_feature_access_manager),
apps_access_manager_(apps_access_manager),
camera_roll_manager_(camera_roll_manager),
browser_tabs_model_provider_(browser_tabs_model_provider) {
pref_change_registrar_.Init(prefs_);
}
MultideviceHandler::~MultideviceHandler() = default;
void MultideviceHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"showMultiDeviceSetupDialog",
base::BindRepeating(&MultideviceHandler::HandleShowMultiDeviceSetupDialog,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"getPageContentData",
base::BindRepeating(&MultideviceHandler::HandleGetPageContent,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"setFeatureEnabledState",
base::BindRepeating(&MultideviceHandler::HandleSetFeatureEnabledState,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"removeHostDevice",
base::BindRepeating(&MultideviceHandler::HandleRemoveHostDevice,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"retryPendingHostSetup",
base::BindRepeating(&MultideviceHandler::HandleRetryPendingHostSetup,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"attemptNotificationSetup",
base::BindRepeating(&MultideviceHandler::HandleAttemptNotificationSetup,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"cancelNotificationSetup",
base::BindRepeating(&MultideviceHandler::HandleCancelNotificationSetup,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"attemptAppsSetup",
base::BindRepeating(&MultideviceHandler::HandleAttemptAppsSetup,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"cancelAppsSetup",
base::BindRepeating(&MultideviceHandler::HandleCancelAppsSetup,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"attemptCombinedFeatureSetup",
base::BindRepeating(
&MultideviceHandler::HandleAttemptCombinedFeatureSetup,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"cancelCombinedFeatureSetup",
base::BindRepeating(&MultideviceHandler::HandleCancelCombinedFeatureSetup,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"attemptFeatureSetupConnection",
base::BindRepeating(
&MultideviceHandler::HandleAttemptFeatureSetupConnection,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"cancelFeatureSetupConnection",
base::BindRepeating(
&MultideviceHandler::HandleCancelFeatureSetupConnection,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"showBrowserSyncSettings",
base::BindRepeating(&MultideviceHandler::HandleShowBrowserSyncSettings,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"logPhoneHubPermissionSetUpScreenAction",
base::BindRepeating(
&MultideviceHandler::LogPhoneHubPermissionSetUpScreenAction,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"logPhoneHubPermissionSetUpButtonClicked",
base::BindRepeating(
&MultideviceHandler::LogPhoneHubPermissionSetUpButtonClicked,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"logPhoneHubPermissionOnboardingSetupMode",
base::BindRepeating(
&MultideviceHandler::LogPhoneHubPermissionOnboardingSetupMode,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"logPhoneHubPermissionOnboardingSetupResult",
base::BindRepeating(
&MultideviceHandler::LogPhoneHubPermissionOnboardingSetupResult,
base::Unretained(this)));
}
void MultideviceHandler::OnJavascriptAllowed() {
if (multidevice_setup_client_) {
multidevice_setup_observation_.Observe(multidevice_setup_client_.get());
}
if (multidevice_feature_access_manager_) {
multidevice_feature_access_manager_observation_.Observe(
multidevice_feature_access_manager_.get());
}
if (apps_access_manager_) {
apps_access_manager_observation_.Observe(apps_access_manager_.get());
}
if (camera_roll_manager_) {
camera_roll_manager_observation_.Observe(camera_roll_manager_.get());
}
if (phonehub::BrowserTabsModelProviderImpl::
IsLacrosSessionSyncFeatureEnabled() &&
browser_tabs_model_provider_) {
browser_tabs_model_provider_observation_.Observe(
browser_tabs_model_provider_.get());
}
if (NearbySharingServiceFactory::IsNearbyShareSupportedForBrowserContext(
Profile::FromWebUI(web_ui()))) {
pref_change_registrar_.Add(
::prefs::kNearbySharingEnabledPrefName,
base::BindRepeating(&MultideviceHandler::OnNearbySharingEnabledChanged,
base::Unretained(this)));
}
if (features::IsEcheSWAEnabled()) {
pref_change_registrar_.Add(
ash::prefs::kEnableAutoScreenLock,
base::BindRepeating(&MultideviceHandler::OnEnableScreenLockChanged,
base::Unretained(this)));
pref_change_registrar_.Add(
phonehub::prefs::kScreenLockStatus,
base::BindRepeating(&MultideviceHandler::OnScreenLockStatusChanged,
base::Unretained(this)));
}
}
void MultideviceHandler::OnJavascriptDisallowed() {
pref_change_registrar_.RemoveAll();
if (multidevice_setup_client_) {
DCHECK(multidevice_setup_observation_.IsObservingSource(
multidevice_setup_client_.get()));
multidevice_setup_observation_.Reset();
}
if (multidevice_feature_access_manager_) {
DCHECK(multidevice_feature_access_manager_observation_.IsObservingSource(
multidevice_feature_access_manager_.get()));
multidevice_feature_access_manager_observation_.Reset();
notification_access_operation_.reset();
}
if (apps_access_manager_) {
DCHECK(apps_access_manager_observation_.IsObservingSource(
apps_access_manager_.get()));
apps_access_manager_observation_.Reset();
apps_access_operation_.reset();
}
if (camera_roll_manager_) {
DCHECK(camera_roll_manager_observation_.IsObservingSource(
camera_roll_manager_.get()));
camera_roll_manager_observation_.Reset();
}
if (phonehub::BrowserTabsModelProviderImpl::
IsLacrosSessionSyncFeatureEnabled() &&
browser_tabs_model_provider_) {
DCHECK(browser_tabs_model_provider_observation_.IsObservingSource(
browser_tabs_model_provider_));
browser_tabs_model_provider_observation_.Reset();
}
// Ensure that pending callbacks do not complete and cause JS to be evaluated.
callback_weak_ptr_factory_.InvalidateWeakPtrs();
}
void MultideviceHandler::OnHostStatusChanged(
const multidevice_setup::MultiDeviceSetupClient::HostStatusWithDevice&
host_status_with_device) {
UpdatePageContent();
}
void MultideviceHandler::OnFeatureStatesChanged(
const multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap&
feature_states_map) {
PA_LOG(INFO) << "Feature states have changed: "
<< multidevice_setup::FeatureStatesMapToString(
feature_states_map);
UpdatePageContent();
}
void MultideviceHandler::OnNotificationAccessChanged() {
UpdatePageContent();
}
void MultideviceHandler::OnCameraRollAccessChanged() {
UpdatePageContent();
}
void MultideviceHandler::OnFeatureSetupRequestSupportedChanged() {
UpdatePageContent();
}
void MultideviceHandler::OnAppsAccessChanged() {
UpdatePageContent();
}
void MultideviceHandler::OnCameraRollViewUiStateUpdated() {
UpdatePageContent();
}
void MultideviceHandler::OnBrowserTabsUpdated(
bool is_sync_enabled,
const std::vector<phonehub::BrowserTabsModel::BrowserTabMetadata>&
browser_tabs_metadata) {
UpdatePageContent();
}
void MultideviceHandler::OnNearbySharingEnabledChanged() {
UpdatePageContent();
}
void MultideviceHandler::UpdatePageContent() {
base::Value::Dict page_content_dictionary =
GeneratePageContentDataDictionary();
PA_LOG(INFO) << "Updating MultiDevice settings page content with: "
<< page_content_dictionary << ".";
FireWebUIListener("settings.updateMultidevicePageContentData",
page_content_dictionary);
}
void MultideviceHandler::HandleShowMultiDeviceSetupDialog(
const base::Value::List& args) {
DCHECK(args.empty());
multidevice_setup::MultiDeviceSetupDialog::Show();
ash::phonehub::util::LogMultiDeviceSetupDialogEntryPoint(
ash::phonehub::util::MultiDeviceSetupDialogEntrypoint::kSettingsPage);
}
void MultideviceHandler::HandleGetPageContent(const base::Value::List& args) {
// This callback is expected to be the first one executed when the page is
// loaded, so it should be the one to allow JS calls.
AllowJavascript();
const base::Value& callback_id = args[0];
DCHECK(callback_id.is_string());
base::Value::Dict page_content_dictionary =
GeneratePageContentDataDictionary();
PA_LOG(INFO) << "Responding to getPageContentData() request with: "
<< page_content_dictionary << ".";
ResolveJavascriptCallback(callback_id, page_content_dictionary);
}
void MultideviceHandler::HandleSetFeatureEnabledState(
const base::Value::List& args) {
const auto& list = args;
DCHECK_GE(list.size(), 3u);
std::string callback_id = list[0].GetString();
int feature_as_int = list[1].GetInt();
auto feature = static_cast<multidevice_setup::mojom::Feature>(feature_as_int);
DCHECK(multidevice_setup::mojom::IsKnownEnumValue(feature));
bool enabled = list[2].GetBool();
std::optional<std::string> auth_token;
if (list.size() >= 4 && list[3].is_string()) {
auth_token = list[3].GetString();
}
multidevice_setup_client_->SetFeatureEnabledState(
feature, enabled, auth_token,
base::BindOnce(&MultideviceHandler::OnSetFeatureStateEnabledResult,
callback_weak_ptr_factory_.GetWeakPtr(), callback_id));
if (enabled && feature == multidevice_setup::mojom::Feature::kPhoneHub) {
phonehub::util::LogFeatureOptInEntryPoint(
phonehub::util::OptInEntryPoint::kSettings);
}
if (enabled &&
feature == multidevice_setup::mojom::Feature::kPhoneHubCameraRoll) {
phonehub::util::LogCameraRollFeatureOptInEntryPoint(
phonehub::util::CameraRollOptInEntryPoint::kSettings);
}
}
void MultideviceHandler::HandleRemoveHostDevice(const base::Value::List& args) {
DCHECK(args.empty());
multidevice_setup_client_->RemoveHostDevice();
}
void MultideviceHandler::HandleRetryPendingHostSetup(
const base::Value::List& args) {
DCHECK(args.empty());
multidevice_setup_client_->RetrySetHostNow(
base::BindOnce(&OnRetrySetHostNowResult));
}
void MultideviceHandler::HandleAttemptNotificationSetup(
const base::Value::List& args) {
DCHECK(features::IsPhoneHubEnabled());
DCHECK(!notification_access_operation_);
phonehub::MultideviceFeatureAccessManager::AccessStatus
notification_access_status =
multidevice_feature_access_manager_->GetNotificationAccessStatus();
if (notification_access_status != phonehub::MultideviceFeatureAccessManager::
AccessStatus::kAvailableButNotGranted) {
PA_LOG(WARNING) << "Cannot request notification access setup flow; current "
<< "status: " << notification_access_status;
return;
}
notification_access_operation_ =
multidevice_feature_access_manager_->AttemptNotificationSetup(
/*delegate=*/this);
DCHECK(notification_access_operation_);
}
void MultideviceHandler::HandleCancelNotificationSetup(
const base::Value::List& args) {
DCHECK(features::IsPhoneHubEnabled());
DCHECK(notification_access_operation_);
notification_access_operation_.reset();
}
void MultideviceHandler::HandleAttemptAppsSetup(const base::Value::List& args) {
DCHECK(features::IsEcheSWAEnabled());
DCHECK(!apps_access_operation_);
phonehub::MultideviceFeatureAccessManager::AccessStatus apps_access_status =
apps_access_manager_->GetAccessStatus();
if (apps_access_status != phonehub::MultideviceFeatureAccessManager::
AccessStatus::kAvailableButNotGranted) {
PA_LOG(WARNING) << "Cannot request apps access setup flow; current "
<< "status: " << apps_access_status;
return;
}
apps_access_operation_ =
apps_access_manager_->AttemptAppsAccessSetup(/*delegate=*/this);
DCHECK(apps_access_operation_);
}
void MultideviceHandler::HandleCancelAppsSetup(const base::Value::List& args) {
DCHECK(features::IsEcheSWAEnabled());
DCHECK(apps_access_operation_);
apps_access_manager_->NotifyAppsAccessCanceled();
apps_access_operation_.reset();
}
void MultideviceHandler::HandleAttemptCombinedFeatureSetup(
const base::Value::List& args) {
bool camera_roll = false;
if (args[0].is_bool()) {
camera_roll = args[0].GetBool();
}
bool notifications = false;
if (args[1].is_bool()) {
notifications = args[1].GetBool();
}
DCHECK(features::IsPhoneHubEnabled());
DCHECK(!combined_access_operation_);
if (!multidevice_feature_access_manager_->GetFeatureSetupRequestSupported()) {
PA_LOG(WARNING) << "Cannot request combined access setup flow; "
<< "FeatureSetupRequest is not supported by the phone.";
return;
}
phonehub::MultideviceFeatureAccessManager::AccessStatus
notification_access_status =
multidevice_feature_access_manager_->GetNotificationAccessStatus();
phonehub::MultideviceFeatureAccessManager::AccessStatus
camera_roll_access_status =
multidevice_feature_access_manager_->GetCameraRollAccessStatus();
if (camera_roll_access_status != phonehub::MultideviceFeatureAccessManager::
AccessStatus::kAvailableButNotGranted &&
camera_roll) {
PA_LOG(WARNING) << "Cannot request combined access setup flow; current "
<< "Camera Roll status: " << camera_roll_access_status;
return;
}
if (notification_access_status != phonehub::MultideviceFeatureAccessManager::
AccessStatus::kAvailableButNotGranted &&
notifications) {
PA_LOG(WARNING) << "Cannot request combined access setup flow; current "
<< "Notification status: " << notification_access_status;
return;
}
combined_access_operation_ =
multidevice_feature_access_manager_->AttemptCombinedFeatureSetup(
camera_roll, notifications, /*delegate=*/this);
DCHECK(combined_access_operation_);
}
void MultideviceHandler::HandleCancelCombinedFeatureSetup(
const base::Value::List& args) {
DCHECK(features::IsPhoneHubEnabled());
DCHECK(combined_access_operation_);
combined_access_operation_.reset();
}
void MultideviceHandler::HandleAttemptFeatureSetupConnection(
const base::Value::List& args) {
DCHECK(features::IsPhoneHubEnabled());
DCHECK(!feature_setup_connection_operation_);
feature_setup_connection_operation_ =
multidevice_feature_access_manager_->AttemptFeatureSetupConnection(this);
DCHECK(feature_setup_connection_operation_);
}
void MultideviceHandler::HandleCancelFeatureSetupConnection(
const base::Value::List& args) {
DCHECK(features::IsPhoneHubEnabled());
DCHECK(feature_setup_connection_operation_);
feature_setup_connection_operation_.reset();
}
void MultideviceHandler::HandleShowBrowserSyncSettings(
const base::Value::List& args) {
ash::NewWindowDelegate::GetPrimary()->OpenUrl(
GURL("chrome://settings/syncSetup/advanced"),
ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
ash::NewWindowDelegate::Disposition::kSwitchToTab);
}
void MultideviceHandler::LogPhoneHubPermissionSetUpScreenAction(
const base::Value::List& args) {
int setup_screen_int = args[0].GetInt();
int setup_action_int = args[1].GetInt();
LogPermissionOnboardingDialogAction(
static_cast<PermissionsOnboardingStep>(setup_screen_int),
static_cast<PermissionsOnboardingScreenEvent>(setup_action_int));
}
void MultideviceHandler::LogPhoneHubPermissionSetUpButtonClicked(
const base::Value::List& args) {
int setup_mode = args[0].GetInt();
LogPermissionOnboardingSettingsClicked(
static_cast<PermissionsOnboardingSetUpMode>(setup_mode));
}
void MultideviceHandler::LogPhoneHubPermissionOnboardingSetupMode(
const base::Value::List& args) {
int setup_mode = args[0].GetInt();
LogPermissionOnboardingSetupMode(
static_cast<PermissionsOnboardingSetUpMode>(setup_mode));
}
void MultideviceHandler::LogPhoneHubPermissionOnboardingSetupResult(
const base::Value::List& args) {
int completed_mode = args[0].GetInt();
LogPermissionOnboardingSetupResult(
static_cast<PermissionsOnboardingSetUpMode>(completed_mode));
}
void MultideviceHandler::OnNotificationStatusChange(
phonehub::NotificationAccessSetupOperation::Status new_status) {
FireWebUIListener("settings.onNotificationAccessSetupStatusChanged",
base::Value(static_cast<int32_t>(new_status)));
if (phonehub::NotificationAccessSetupOperation::IsFinalStatus(new_status)) {
notification_access_operation_.reset();
}
}
void MultideviceHandler::OnAppsStatusChange(
eche_app::AppsAccessSetupOperation::Status new_status) {
FireWebUIListener("settings.onAppsAccessSetupStatusChanged",
base::Value(static_cast<int32_t>(new_status)));
if (eche_app::AppsAccessSetupOperation::IsFinalStatus(new_status)) {
apps_access_operation_.reset();
}
}
void MultideviceHandler::OnCombinedStatusChange(
phonehub::CombinedAccessSetupOperation::Status new_status) {
FireWebUIListener("settings.onCombinedAccessSetupStatusChanged",
base::Value(static_cast<int32_t>(new_status)));
if (phonehub::CombinedAccessSetupOperation::IsFinalStatus(new_status)) {
combined_access_operation_.reset();
}
}
void MultideviceHandler::OnFeatureSetupConnectionStatusChange(
phonehub::FeatureSetupConnectionOperation::Status new_status) {
FireWebUIListener("settings.onFeatureSetupConnectionStatusChanged",
base::Value(static_cast<int32_t>(new_status)));
if (phonehub::FeatureSetupConnectionOperation::IsFinalStatus(new_status)) {
feature_setup_connection_operation_.reset();
}
}
void MultideviceHandler::OnSetFeatureStateEnabledResult(
const std::string& js_callback_id,
bool success) {
ResolveJavascriptCallback(base::Value(js_callback_id), base::Value(success));
}
base::Value::Dict MultideviceHandler::GeneratePageContentDataDictionary() {
base::Value::Dict page_content_dictionary;
multidevice_setup::MultiDeviceSetupClient::HostStatusWithDevice
host_status_with_device = GetHostStatusWithDevice();
multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap feature_states =
GetFeatureStatesMap();
page_content_dictionary.Set(
kPageContentDataModeKey,
static_cast<int32_t>(host_status_with_device.first));
page_content_dictionary.Set(
kPageContentDataBetterTogetherStateKey,
static_cast<int32_t>(
feature_states
[multidevice_setup::mojom::Feature::kBetterTogetherSuite]));
page_content_dictionary.Set(
kPageContentDataInstantTetheringStateKey,
static_cast<int32_t>(
feature_states
[multidevice_setup::mojom::Feature::kInstantTethering]));
page_content_dictionary.Set(
kPageContentDataSmartLockStateKey,
static_cast<int32_t>(
feature_states[multidevice_setup::mojom::Feature::kSmartLock]));
page_content_dictionary.Set(
kPageContentDataPhoneHubStateKey,
static_cast<int32_t>(
feature_states[multidevice_setup::mojom::Feature::kPhoneHub]));
auto cameraRoll_feature_state =
base::FeatureList::IsEnabled(ash::features::kPhoneHubCameraRoll)
? feature_states
[multidevice_setup::mojom::Feature::kPhoneHubCameraRoll]
: multidevice_setup::mojom::FeatureState::kNotSupportedByChromebook;
page_content_dictionary.Set(kPageContentDataPhoneHubCameraRollStateKey,
static_cast<int32_t>(cameraRoll_feature_state));
page_content_dictionary.Set(
kPageContentDataPhoneHubNotificationsStateKey,
static_cast<int32_t>(
feature_states
[multidevice_setup::mojom::Feature::kPhoneHubNotifications]));
page_content_dictionary.Set(
kPageContentDataPhoneHubTaskContinuationStateKey,
static_cast<int32_t>(
feature_states
[multidevice_setup::mojom::Feature::kPhoneHubTaskContinuation]));
auto eche_feature_state =
base::FeatureList::IsEnabled(ash::features::kEcheSWA)
? feature_states[multidevice_setup::mojom::Feature::kEche]
: multidevice_setup::mojom::FeatureState::kNotSupportedByChromebook;
page_content_dictionary.Set(kPageContentDataPhoneHubAppsStateKey,
static_cast<int32_t>(eche_feature_state));
page_content_dictionary.Set(
kPageContentDataWifiSyncStateKey,
static_cast<int32_t>(
feature_states[multidevice_setup::mojom::Feature::kWifiSync]));
if (host_status_with_device.second) {
page_content_dictionary.Set(kPageContentDataHostDeviceNameKey,
host_status_with_device.second->name());
}
phonehub::MultideviceFeatureAccessManager::AccessStatus
notification_access_status = phonehub::MultideviceFeatureAccessManager::
AccessStatus::kAvailableButNotGranted;
phonehub::MultideviceFeatureAccessManager::AccessProhibitedReason reason =
phonehub::MultideviceFeatureAccessManager::AccessProhibitedReason::
kUnknown;
if (multidevice_feature_access_manager_) {
notification_access_status =
multidevice_feature_access_manager_->GetNotificationAccessStatus();
reason = multidevice_feature_access_manager_
->GetNotificationAccessProhibitedReason();
}
page_content_dictionary.Set(kNotificationAccessStatus,
static_cast<int32_t>(notification_access_status));
page_content_dictionary.Set(kNotificationAccessProhibitedReason,
static_cast<int32_t>(reason));
phonehub::MultideviceFeatureAccessManager::AccessStatus
camera_roll_access_status = phonehub::MultideviceFeatureAccessManager::
AccessStatus::kAvailableButNotGranted;
if (multidevice_feature_access_manager_) {
camera_roll_access_status =
multidevice_feature_access_manager_->GetCameraRollAccessStatus();
}
page_content_dictionary.Set(kCameraRollAccessStatus,
static_cast<int32_t>(camera_roll_access_status));
phonehub::MultideviceFeatureAccessManager::AccessStatus apps_access_status =
phonehub::MultideviceFeatureAccessManager::AccessStatus::
kAvailableButNotGranted;
if (apps_access_manager_) {
apps_access_status = apps_access_manager_->GetAccessStatus();
}
page_content_dictionary.Set(kAppsAccessStatus,
static_cast<int32_t>(apps_access_status));
bool is_camera_roll_file_permission_granted = false;
if (camera_roll_manager_) {
is_camera_roll_file_permission_granted =
camera_roll_manager_->ui_state() !=
phonehub::CameraRollManager::CameraRollUiState::NO_STORAGE_PERMISSION;
}
page_content_dictionary.Set(kIsCameraRollFilePermissionGranted,
is_camera_roll_file_permission_granted);
bool is_nearby_share_disallowed_by_policy =
NearbySharingServiceFactory::IsNearbyShareSupportedForBrowserContext(
Profile::FromWebUI(web_ui())) &&
(GetNearbyShareEnabledState(prefs_) ==
NearbyShareEnabledState::kDisallowedByPolicy);
page_content_dictionary.Set(kIsNearbyShareDisallowedByPolicy,
is_nearby_share_disallowed_by_policy);
bool is_phone_hub_permissions_dialog_supported =
features::IsEcheSWAEnabled() || features::IsPhoneHubCameraRollEnabled();
page_content_dictionary.Set(kIsPhoneHubPermissionsDialogSupported,
is_phone_hub_permissions_dialog_supported);
page_content_dictionary.Set(kIsPhoneHubFeatureCombinedSetupSupported,
multidevice_feature_access_manager_
? multidevice_feature_access_manager_
->GetFeatureSetupRequestSupported()
: false);
bool is_lacros_session_sync_feature_enabled = phonehub::
BrowserTabsModelProviderImpl::IsLacrosSessionSyncFeatureEnabled();
page_content_dictionary.Set(kIsChromeOSSyncedSessionSharingEnabled,
is_lacros_session_sync_feature_enabled);
if (is_lacros_session_sync_feature_enabled && browser_tabs_model_provider_) {
page_content_dictionary.Set(
kIsLacrosTabSyncEnabled,
browser_tabs_model_provider_->IsBrowserTabSyncEnabled());
} else {
page_content_dictionary.Set(kIsLacrosTabSyncEnabled, false);
}
return page_content_dictionary;
}
bool MultideviceHandler::IsAuthTokenValid(const std::string& auth_token) {
return ash::AuthSessionStorage::Get()->IsValid(auth_token);
}
multidevice_setup::MultiDeviceSetupClient::HostStatusWithDevice
MultideviceHandler::GetHostStatusWithDevice() {
if (multidevice_setup_client_) {
return multidevice_setup_client_->GetHostStatus();
}
return multidevice_setup::MultiDeviceSetupClient::
GenerateDefaultHostStatusWithDevice();
}
multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap
MultideviceHandler::GetFeatureStatesMap() {
if (multidevice_setup_client_) {
return multidevice_setup_client_->GetFeatureStates();
}
PA_LOG(WARNING)
<< "MultiDevice setup client missing. Responding to "
"GetFeatureStatesMap() request by generating default feature map.";
return multidevice_setup::MultiDeviceSetupClient::
GenerateDefaultFeatureStatesMap(
multidevice_setup::mojom::FeatureState::kProhibitedByPolicy);
}
void MultideviceHandler::OnEnableScreenLockChanged() {
// We need to use FireWebUIListener to update value dynamically because
// loadTimeData is not recreated on refresh.
const bool is_screen_lock_enabled =
SessionControllerClientImpl::CanLockScreen() &&
SessionControllerClientImpl::ShouldLockScreenAutomatically();
FireWebUIListener("settings.OnEnableScreenLockChanged",
base::Value(is_screen_lock_enabled));
}
void MultideviceHandler::OnScreenLockStatusChanged() {
// We need to use FireWebUIListener to update value dynamically because
// loadTimeData is not recreated on refresh.
const bool is_phone_screen_lock_enabled =
static_cast<phonehub::ScreenLockManager::LockStatus>(
prefs_->GetInteger(phonehub::prefs::kScreenLockStatus)) ==
phonehub::ScreenLockManager::LockStatus::kLockedOn;
FireWebUIListener("settings.OnScreenLockStatusChanged",
base::Value(is_phone_screen_lock_enabled));
}
} // namespace ash::settings