| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/webui/projector_app/untrusted_projector_page_handler_impl.h" |
| |
| #include <memory> |
| #include <vector> |
| |
| #include "ash/constants/ash_pref_names.h" |
| #include "ash/public/cpp/projector/projector_controller.h" |
| #include "ash/public/cpp/projector/projector_new_screencast_precondition.h" |
| #include "ash/webui/projector_app/mojom/untrusted_projector.mojom.h" |
| #include "ash/webui/projector_app/projector_app_client.h" |
| #include "ash/webui/projector_app/projector_oauth_token_fetcher.h" |
| #include "ash/webui/projector_app/projector_xhr_sender.h" |
| #include "ash/webui/projector_app/public/mojom/projector_types.mojom-forward.h" |
| #include "ash/webui/projector_app/public/mojom/projector_types.mojom.h" |
| #include "base/files/safe_base_name.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/signin/public/identity_manager/account_info.h" |
| #include "url/gurl.h" |
| |
| namespace ash { |
| |
| namespace { |
| |
| std::vector<ash::projector::mojom::PendingScreencastPtr> |
| GetPendingScreencastsFromContainers( |
| const PendingScreencastContainerSet& pending_screencast_containers) { |
| std::vector<ash::projector::mojom::PendingScreencastPtr> result; |
| for (const auto& container : pending_screencast_containers) { |
| result.push_back(container.pending_screencast().Clone()); |
| } |
| return result; |
| } |
| |
| inline bool IsBoolPref(projector::mojom::PrefsThatProjectorCanAskFor pref) { |
| return pref == projector::mojom::PrefsThatProjectorCanAskFor:: |
| kProjectorCreationFlowEnabled || |
| pref == projector::mojom::PrefsThatProjectorCanAskFor:: |
| kProjectorExcludeTranscriptDialogShown; |
| } |
| |
| inline bool IsIntPref(projector::mojom::PrefsThatProjectorCanAskFor pref) { |
| return pref == projector::mojom::PrefsThatProjectorCanAskFor:: |
| kProjectorGalleryOnboardingShowCount || |
| pref == projector::mojom::PrefsThatProjectorCanAskFor:: |
| kProjectorViewerOnboardingShowCount; |
| } |
| |
| std::string GetPrefName(projector::mojom::PrefsThatProjectorCanAskFor pref) { |
| switch (pref) { |
| case projector::mojom::PrefsThatProjectorCanAskFor:: |
| kProjectorCreationFlowEnabled: |
| return ash::prefs::kProjectorCreationFlowEnabled; |
| case projector::mojom::PrefsThatProjectorCanAskFor:: |
| kProjectorExcludeTranscriptDialogShown: |
| return ash::prefs::kProjectorExcludeTranscriptDialogShown; |
| case projector::mojom::PrefsThatProjectorCanAskFor:: |
| kProjectorViewerOnboardingShowCount: |
| return ash::prefs::kProjectorViewerOnboardingShowCount; |
| case projector::mojom::PrefsThatProjectorCanAskFor:: |
| kProjectorGalleryOnboardingShowCount: |
| return ash::prefs::kProjectorGalleryOnboardingShowCount; |
| } |
| |
| NOTREACHED_NORETURN(); |
| } |
| |
| } // namespace |
| |
| UntrustedProjectorPageHandlerImpl::UntrustedProjectorPageHandlerImpl( |
| mojo::PendingReceiver<projector::mojom::UntrustedProjectorPageHandler> |
| receiver, |
| mojo::PendingRemote<projector::mojom::UntrustedProjectorPage> |
| projector_remote, |
| PrefService* pref_service) |
| : receiver_(this, std::move(receiver)), |
| projector_remote_(std::move(projector_remote)), |
| pref_service_(pref_service), |
| xhr_sender_(ProjectorAppClient::Get()->GetUrlLoaderFactory()) { |
| ProjectorAppClient::Get()->AddObserver(this); |
| } |
| |
| UntrustedProjectorPageHandlerImpl::~UntrustedProjectorPageHandlerImpl() { |
| ProjectorAppClient::Get()->RemoveObserver(this); |
| } |
| |
| void UntrustedProjectorPageHandlerImpl::OnNewScreencastPreconditionChanged( |
| const NewScreencastPrecondition& precondition) { |
| projector_remote_->OnNewScreencastPreconditionChanged(precondition); |
| } |
| |
| void UntrustedProjectorPageHandlerImpl::OnSodaProgress(int progress) { |
| projector_remote_->OnSodaInstallProgressUpdated(progress); |
| } |
| |
| void UntrustedProjectorPageHandlerImpl::OnSodaError() { |
| projector_remote_->OnSodaInstallError(); |
| } |
| |
| void UntrustedProjectorPageHandlerImpl::OnSodaInstalled() { |
| projector_remote_->OnSodaInstalled(); |
| } |
| |
| void UntrustedProjectorPageHandlerImpl::OnScreencastsPendingStatusChanged( |
| const PendingScreencastContainerSet& pending_screencast_containers) { |
| projector_remote_->OnScreencastsStateChange( |
| GetPendingScreencastsFromContainers(pending_screencast_containers)); |
| } |
| |
| void UntrustedProjectorPageHandlerImpl::GetNewScreencastPrecondition( |
| |
| GetNewScreencastPreconditionCallback callback) { |
| std::move(callback).Run( |
| ProjectorController::Get()->GetNewScreencastPrecondition()); |
| } |
| |
| void UntrustedProjectorPageHandlerImpl::ShouldDownloadSoda( |
| ShouldDownloadSodaCallback callback) { |
| bool should_download = ProjectorAppClient::Get()->ShouldDownloadSoda(); |
| std::move(callback).Run(should_download); |
| } |
| void UntrustedProjectorPageHandlerImpl::InstallSoda( |
| InstallSodaCallback callback) { |
| ProjectorAppClient::Get()->InstallSoda(); |
| // We have successfully triggered the request. |
| std::move(callback).Run(/*triggered=*/true); |
| } |
| |
| void UntrustedProjectorPageHandlerImpl::GetPendingScreencasts( |
| |
| GetPendingScreencastsCallback callback) { |
| auto pending_screencast = GetPendingScreencastsFromContainers( |
| ProjectorAppClient::Get()->GetPendingScreencasts()); |
| std::move(callback).Run(std::move(pending_screencast)); |
| } |
| |
| void UntrustedProjectorPageHandlerImpl::GetUserPref( |
| projector::mojom::PrefsThatProjectorCanAskFor pref, |
| GetUserPrefCallback callback) { |
| const auto& value = pref_service_->GetValue(GetPrefName(pref)); |
| |
| bool valid_request = (value.is_bool() && IsBoolPref(pref)) || |
| (value.is_int() && IsIntPref(pref)); |
| |
| if (!valid_request) { |
| receiver_.ReportBadMessage("Using disallowed type for pref."); |
| return; |
| } |
| |
| std::move(callback).Run(value.Clone()); |
| } |
| |
| void UntrustedProjectorPageHandlerImpl::SetUserPref( |
| projector::mojom::PrefsThatProjectorCanAskFor pref, |
| base::Value value, |
| SetUserPrefCallback callback) { |
| bool valid_request = (value.is_bool() && IsBoolPref(pref)) || |
| (value.is_int() && IsIntPref(pref)); |
| |
| if (!valid_request) { |
| receiver_.ReportBadMessage("Using disallowed type for pref."); |
| return; |
| } |
| |
| pref_service_->Set(GetPrefName(pref), std::move(value)); |
| std::move(callback).Run(); |
| } |
| |
| void UntrustedProjectorPageHandlerImpl::OpenFeedbackDialog( |
| OpenFeedbackDialogCallback callback) { |
| ProjectorAppClient::Get()->OpenFeedbackDialog(); |
| std::move(callback).Run(); |
| } |
| |
| void UntrustedProjectorPageHandlerImpl::StartProjectorSession( |
| const base::SafeBaseName& storage_dir_name, |
| StartProjectorSessionCallback callback) { |
| auto* controller = ProjectorController::Get(); |
| |
| if (controller->GetNewScreencastPrecondition().state != |
| NewScreencastPreconditionState::kEnabled) { |
| std::move(callback).Run(/*success=*/false); |
| return; |
| } |
| |
| controller->StartProjectorSession(storage_dir_name); |
| std::move(callback).Run(/*success=*/true); |
| } |
| |
| void UntrustedProjectorPageHandlerImpl::SendXhr( |
| const GURL& url, |
| projector::mojom::RequestType method, |
| const std::optional<std::string>& request_body, |
| bool use_credentials, |
| bool use_api_key, |
| const std::optional<base::flat_map<std::string, std::string>>& headers, |
| const std::optional<std::string>& account_email, |
| SendXhrCallback callback) { |
| CHECK(url.is_valid()); |
| xhr_sender_.Send( |
| url, method, request_body, use_credentials, use_api_key, |
| base::BindOnce(&UntrustedProjectorPageHandlerImpl::OnXhrRequestCompleted, |
| GetWeakPtr(), std::move(callback)), |
| headers, account_email); |
| } |
| |
| void UntrustedProjectorPageHandlerImpl::GetAccounts( |
| GetAccountsCallback callback) { |
| const std::vector<AccountInfo> accounts = |
| ProjectorOAuthTokenFetcher::GetAccounts(); |
| const CoreAccountInfo primary_account = |
| ProjectorOAuthTokenFetcher::GetPrimaryAccountInfo(); |
| |
| std::vector<projector::mojom::AccountPtr> mojo_accounts; |
| mojo_accounts.reserve(accounts.size()); |
| |
| for (const auto& info : accounts) { |
| auto account = projector::mojom::Account::New(); |
| account->email = info.email; |
| account->is_primary_user = info.gaia == primary_account.gaia; |
| mojo_accounts.push_back(std::move(account)); |
| } |
| |
| std::move(callback).Run(std::move(mojo_accounts)); |
| } |
| |
| void UntrustedProjectorPageHandlerImpl::GetVideo( |
| const std::string& video_file_id, |
| const std::optional<std::string>& resource_key, |
| GetVideoCallback callback) { |
| ProjectorAppClient::Get()->GetVideo( |
| video_file_id, resource_key, |
| base::BindOnce(&UntrustedProjectorPageHandlerImpl::OnVideoLocated, |
| GetWeakPtr(), std::move(callback))); |
| } |
| |
| void UntrustedProjectorPageHandlerImpl::OnVideoLocated( |
| projector::mojom::UntrustedProjectorPageHandler::GetVideoCallback callback, |
| projector::mojom::GetVideoResultPtr result) { |
| std::move(callback).Run(std::move(result)); |
| } |
| |
| base::WeakPtr<UntrustedProjectorPageHandlerImpl> |
| UntrustedProjectorPageHandlerImpl::GetWeakPtr() { |
| return weak_ptr_factory_.GetWeakPtr(); |
| } |
| |
| void UntrustedProjectorPageHandlerImpl::OnXhrRequestCompleted( |
| SendXhrCallback callback, |
| projector::mojom::XhrResponsePtr xhr_responose) { |
| // If the request made is an unsupported url, then |
| // crash the renderer. |
| if (xhr_responose->response_code == |
| projector::mojom::XhrResponseCode::kUnsupportedURL) { |
| receiver_.ReportBadMessage("Unsupported url requested."); |
| return; |
| } |
| |
| std::move(callback).Run(std::move(xhr_responose)); |
| } |
| |
| } // namespace ash |