1 // Copyright 2020 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_CHROMEOS_CAMERA_MIC_VM_CAMERA_MIC_MANAGER_H_ 6 #define CHROME_BROWSER_CHROMEOS_CAMERA_MIC_VM_CAMERA_MIC_MANAGER_H_ 7 8 #include <memory> 9 #include "base/callback_forward.h" 10 #include "base/containers/flat_map.h" 11 #include "base/memory/weak_ptr.h" 12 #include "base/observer_list.h" 13 #include "base/observer_list_types.h" 14 #include "base/timer/timer.h" 15 #include "components/keyed_service/core/keyed_service.h" 16 #include "ui/message_center/public/cpp/notification.h" 17 #include "ui/message_center/public/cpp/notification_delegate.h" 18 19 class Profile; 20 21 namespace chromeos { 22 23 // This class manages camera/mic access (and the access notifications) for VMs 24 // (crostini and parallels for now). Like all the VMs, it is only available for 25 // the primary and non-incognito profile. We might need to change this if we 26 // extend this class to support the browser, in which case we will also need to 27 // make the notification ids different for different profiles. 28 class VmCameraMicManager : public KeyedService { 29 public: 30 enum class VmType { kCrostiniVm, kPluginVm }; 31 32 enum class DeviceType { 33 kMic, 34 kCamera, 35 }; 36 37 class Observer : public base::CheckedObserver { 38 public: OnVmCameraMicActiveChanged(VmCameraMicManager *)39 virtual void OnVmCameraMicActiveChanged(VmCameraMicManager*) {} 40 }; 41 42 // Return nullptr if the profile is non-primary or incognito. 43 static VmCameraMicManager* GetForProfile(Profile* profile); 44 45 explicit VmCameraMicManager(Profile* profile); 46 ~VmCameraMicManager() override; 47 48 VmCameraMicManager(const VmCameraMicManager&) = delete; 49 VmCameraMicManager& operator=(const VmCameraMicManager&) = delete; 50 51 void AddObserver(Observer* observer); 52 void RemoveObserver(Observer* observer); 53 54 void SetActive(VmType vm, DeviceType device, bool active); 55 bool GetActive(VmType vm, DeviceType device) const; 56 // Return true if any of the VMs is using the device. 57 bool GetDeviceActive(DeviceType device) const; 58 59 private: 60 using ActiveMap = base::flat_map<std::pair<VmType, DeviceType>, bool>; 61 62 class VmNotificationObserver : public message_center::NotificationObserver { 63 public: 64 using OpenSettingsFunction = base::RepeatingCallback<void(Profile*)>; 65 66 VmNotificationObserver(Profile* profile, 67 OpenSettingsFunction open_settings); 68 ~VmNotificationObserver(); 69 70 base::WeakPtr<NotificationObserver> GetWeakPtr(); 71 72 // message_center::NotificationObserver: 73 void Click(const base::Optional<int>& button_index, 74 const base::Optional<base::string16>& reply) override; 75 76 private: 77 Profile* const profile_; 78 OpenSettingsFunction open_settings_; 79 base::WeakPtrFactory<VmNotificationObserver> weak_ptr_factory_{this}; 80 }; 81 82 void NotifyActiveChanged(); 83 84 void OpenNotification(VmType vm, DeviceType device); 85 void CloseNotification(VmType vm, DeviceType device); 86 87 Profile* const profile_; 88 VmNotificationObserver crostini_vm_notification_observer_; 89 VmNotificationObserver plugin_vm_notification_observer_; 90 ActiveMap active_map_; 91 92 base::RetainingOneShotTimer observer_timer_; 93 base::ObserverList<Observer> observers_; 94 }; 95 96 } // namespace chromeos 97 98 #endif // CHROME_BROWSER_CHROMEOS_CAMERA_MIC_VM_CAMERA_MIC_MANAGER_H_ 99