| // 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. |
| |
| #ifndef CHROME_BROWSER_UI_ASH_APP_ACCESS_APP_ACCESS_NOTIFIER_H_ |
| #define CHROME_BROWSER_UI_ASH_APP_ACCESS_APP_ACCESS_NOTIFIER_H_ |
| |
| #include <list> |
| #include <map> |
| #include <optional> |
| #include <string> |
| #include <vector> |
| |
| #include "base/memory/weak_ptr.h" |
| #include "base/scoped_observation.h" |
| #include "components/account_id/account_id.h" |
| #include "components/services/app_service/public/cpp/app_capability_access_cache.h" |
| #include "components/services/app_service/public/cpp/capability_access_update.h" |
| #include "components/session_manager/core/session_manager_observer.h" |
| #include "components/user_manager/user_manager.h" |
| |
| namespace apps { |
| class AppCapabilityAccessCache; |
| class AppRegistryCache; |
| } // namespace apps |
| |
| namespace session_manager { |
| class SessionManager; |
| } // namespace session_manager |
| |
| // This class is responsible for observing AppCapabilityAccessCache, notifying |
| // to appropriate entities when an app is accessing camera/microphone. |
| class AppAccessNotifier |
| : public apps::AppCapabilityAccessCache::Observer, |
| public session_manager::SessionManagerObserver, |
| public user_manager::UserManager::UserSessionStateObserver { |
| public: |
| AppAccessNotifier(); |
| AppAccessNotifier(const AppAccessNotifier&) = delete; |
| AppAccessNotifier& operator=(const AppAccessNotifier&) = delete; |
| ~AppAccessNotifier() override; |
| |
| // apps::AppCapabilityAccessCache::Observer |
| void OnCapabilityAccessUpdate( |
| const apps::CapabilityAccessUpdate& update) override; |
| void OnAppCapabilityAccessCacheWillBeDestroyed( |
| apps::AppCapabilityAccessCache* cache) override; |
| |
| // session_manager::SessionManagerObserver |
| void OnSessionStateChanged() override; |
| |
| // user_manager::UserManager::UserSessionStateObserver |
| void ActiveUserChanged(user_manager::User* active_user) override; |
| |
| // Get the app short name of the app with `app_id`. |
| static std::optional<std::u16string> GetAppShortNameFromAppId( |
| std::string app_id); |
| |
| // Launch the native settings page of the app with `app_id`. |
| static void LaunchAppSettings(const std::string& app_id); |
| |
| // Returns names of apps accessing camera. |
| std::vector<std::u16string> GetAppsAccessingCamera(); |
| |
| // Returns names of apps accessing microphone. |
| std::vector<std::u16string> GetAppsAccessingMicrophone(); |
| |
| protected: |
| // Returns the active user's account ID if we have an active user, an empty |
| // account ID otherwise. |
| virtual AccountId GetActiveUserAccountId(); |
| |
| // Compares the active user's account ID to our last known value and, if the |
| // ID has changed, then updates the AppCapabilityAccessCache that we observe |
| // as well as the last known account ID. |
| void CheckActiveUserChanged(); |
| |
| private: |
| friend class AppAccessNotifierTest; |
| |
| // Returns the AppCapabilityAccessCache associated with the active user's |
| // account ID. |
| apps::AppCapabilityAccessCache* GetActiveUserAppCapabilityAccessCache(); |
| |
| // Get the current active instance of AppRegistryCache. |
| static apps::AppRegistryCache* GetActiveUserAppRegistryCache(); |
| |
| // List of IDs of apps that have attempted to use the microphone, in order of |
| // most-recently-launched. |
| using MruAppIdList = std::list<std::string>; |
| |
| // Each user has their own list of MRU apps. It's intended to persist across |
| // multiple logouts/logins, and we specifically don't ever clear it. This is |
| // used for the microphone and camera mute notifications. |
| using MruAppIdMap = std::map<AccountId, MruAppIdList>; |
| |
| // A helper function for implementation of GetAppsAccessing*. |
| std::vector<std::u16string> GetAppsAccessingSensor( |
| const MruAppIdList* app_id_list, |
| base::OnceCallback<std::set<std::string>(apps::AppCapabilityAccessCache&)> |
| app_getter); |
| |
| // A helper to check if `app_id` can be found in `id_map` for the active user. |
| bool MapContainsAppId(const MruAppIdMap& id_map, const std::string& app_id); |
| |
| MruAppIdMap mic_using_app_ids_; |
| MruAppIdMap camera_using_app_ids_; |
| |
| // Account ID of the last known active user. |
| AccountId active_user_account_id_ = EmptyAccountId(); |
| |
| // Observations. |
| base::ScopedObservation<session_manager::SessionManager, |
| session_manager::SessionManagerObserver> |
| session_manager_observation_{this}; |
| base::ScopedObservation<user_manager::UserManager, |
| user_manager::UserManager::UserSessionStateObserver> |
| user_session_state_observation_{this}; |
| base::ScopedObservation<apps::AppCapabilityAccessCache, |
| apps::AppCapabilityAccessCache::Observer> |
| app_capability_access_cache_observation_{this}; |
| |
| base::WeakPtrFactory<AppAccessNotifier> weak_ptr_factory_{this}; |
| }; |
| |
| #endif // CHROME_BROWSER_UI_ASH_APP_ACCESS_APP_ACCESS_NOTIFIER_H_ |