| // Copyright 2021 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/settings/ash/guest_os_handler.h" |
| |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/functional/bind.h" |
| #include "base/functional/callback_helpers.h" |
| #include "base/strings/stringprintf.h" |
| #include "chrome/browser/ash/file_manager/path_util.h" |
| #include "chrome/browser/ash/guest_os/guest_os_share_path.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "content/public/browser/browser_thread.h" |
| |
| namespace ash::settings { |
| |
| namespace { |
| |
| base::Value::List GetSharableUsbDevices(CrosUsbDetector* detector) { |
| base::Value::List usb_devices_list; |
| for (const auto& device : detector->GetShareableDevices()) { |
| base::Value::Dict device_info; |
| device_info.Set("guid", device.guid); |
| device_info.Set("label", device.label); |
| if (device.shared_guest_id.has_value()) { |
| base::Value::Dict guest_id; |
| guest_id.Set("vm_name", device.shared_guest_id->vm_name); |
| guest_id.Set("container_name", device.shared_guest_id->container_name); |
| device_info.Set("guestId", std::move(guest_id)); |
| } |
| device_info.Set("vendorId", base::StringPrintf("%04x", device.vendor_id)); |
| device_info.Set("productId", base::StringPrintf("%04x", device.product_id)); |
| device_info.Set("promptBeforeSharing", device.prompt_before_sharing); |
| usb_devices_list.Append(std::move(device_info)); |
| } |
| return usb_devices_list; |
| } |
| |
| } // namespace |
| |
| GuestOsHandler::GuestOsHandler(Profile* profile) : profile_(profile) {} |
| |
| GuestOsHandler::~GuestOsHandler() = default; |
| |
| void GuestOsHandler::RegisterMessages() { |
| web_ui()->RegisterMessageCallback( |
| "getGuestOsSharedPathsDisplayText", |
| base::BindRepeating( |
| &GuestOsHandler::HandleGetGuestOsSharedPathsDisplayText, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback( |
| "removeGuestOsSharedPath", |
| base::BindRepeating(&GuestOsHandler::HandleRemoveGuestOsSharedPath, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback( |
| "notifyGuestOsSharedUsbDevicesPageReady", |
| base::BindRepeating( |
| &GuestOsHandler::HandleNotifyGuestOsSharedUsbDevicesPageReady, |
| weak_ptr_factory_.GetWeakPtr())); |
| web_ui()->RegisterMessageCallback( |
| "setGuestOsUsbDeviceShared", |
| base::BindRepeating(&GuestOsHandler::HandleSetGuestOsUsbDeviceShared, |
| weak_ptr_factory_.GetWeakPtr())); |
| } |
| |
| void GuestOsHandler::OnJavascriptAllowed() { |
| if (auto* detector = CrosUsbDetector::Get()) { |
| cros_usb_device_observation_.Observe(detector); |
| } |
| } |
| |
| void GuestOsHandler::OnJavascriptDisallowed() { |
| cros_usb_device_observation_.Reset(); |
| } |
| |
| void GuestOsHandler::HandleGetGuestOsSharedPathsDisplayText( |
| const base::Value::List& args) { |
| AllowJavascript(); |
| CHECK_EQ(2U, args.size()); |
| std::string callback_id = args[0].GetString(); |
| |
| base::Value::List texts; |
| for (const auto& path : args[1].GetList()) { |
| texts.Append(file_manager::util::GetPathDisplayTextForSettings( |
| profile_, path.GetString())); |
| } |
| ResolveJavascriptCallback(base::Value(callback_id), texts); |
| } |
| |
| void GuestOsHandler::HandleRemoveGuestOsSharedPath( |
| const base::Value::List& args) { |
| CHECK_EQ(3U, args.size()); |
| std::string callback_id = args[0].GetString(); |
| std::string vm_name = args[1].GetString(); |
| std::string path = args[2].GetString(); |
| |
| guest_os::GuestOsSharePath::GetForProfile(profile_)->UnsharePath( |
| vm_name, base::FilePath(path), |
| /*unpersist=*/true, |
| base::BindOnce(&GuestOsHandler::OnGuestOsSharedPathRemoved, |
| weak_ptr_factory_.GetWeakPtr(), callback_id, path)); |
| } |
| |
| void GuestOsHandler::OnGuestOsSharedPathRemoved( |
| const std::string& callback_id, |
| const std::string& path, |
| bool success, |
| const std::string& failure_reason) { |
| if (!success) { |
| LOG(ERROR) << "Error unsharing " << path << ": " << failure_reason; |
| } |
| ResolveJavascriptCallback(base::Value(callback_id), base::Value(success)); |
| } |
| |
| void GuestOsHandler::HandleNotifyGuestOsSharedUsbDevicesPageReady( |
| const base::Value::List& args) { |
| AllowJavascript(); |
| OnUsbDevicesChanged(); |
| } |
| |
| void GuestOsHandler::HandleSetGuestOsUsbDeviceShared( |
| const base::Value::List& args) { |
| CHECK_EQ(4U, args.size()); |
| CrosUsbDetector* detector = CrosUsbDetector::Get(); |
| if (!detector) |
| return; |
| |
| const auto guest_id = |
| guest_os::GuestId(args[0].GetString(), args[1].GetString()); |
| const std::string& guid = args[2].GetString(); |
| bool shared = args[3].GetBool(); |
| |
| if (shared) { |
| detector->AttachUsbDeviceToGuest(guest_id, guid, base::DoNothing()); |
| return; |
| } |
| detector->DetachUsbDeviceFromVm(guest_id.vm_name, guid, base::DoNothing()); |
| } |
| |
| void GuestOsHandler::OnUsbDevicesChanged() { |
| CrosUsbDetector* detector = CrosUsbDetector::Get(); |
| DCHECK(detector); // This callback is called by the detector. |
| FireWebUIListener("guest-os-shared-usb-devices-changed", |
| GetSharableUsbDevices(detector)); |
| } |
| |
| } // namespace ash::settings |