| // 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 CHROMEOS_ASH_COMPONENTS_NETWORK_CELLULAR_ESIM_PROFILE_HANDLER_H_ | 
 | #define CHROMEOS_ASH_COMPONENTS_NETWORK_CELLULAR_ESIM_PROFILE_HANDLER_H_ | 
 |  | 
 | #include <memory> | 
 | #include <vector> | 
 |  | 
 | #include "base/component_export.h" | 
 | #include "base/memory/raw_ptr.h" | 
 | #include "base/memory/weak_ptr.h" | 
 | #include "base/observer_list.h" | 
 | #include "base/observer_list_types.h" | 
 | #include "chromeos/ash/components/dbus/hermes/hermes_euicc_client.h" | 
 | #include "chromeos/ash/components/dbus/hermes/hermes_manager_client.h" | 
 | #include "chromeos/ash/components/dbus/hermes/hermes_profile_client.h" | 
 | #include "chromeos/ash/components/network/cellular_esim_profile.h" | 
 | #include "chromeos/ash/components/network/cellular_inhibitor.h" | 
 | #include "chromeos/ash/services/cellular_setup/public/mojom/esim_manager.mojom.h" | 
 | #include "components/prefs/pref_service.h" | 
 |  | 
 | class PrefService; | 
 |  | 
 | namespace ash { | 
 |  | 
 | class NetworkStateHandler; | 
 |  | 
 | // Source of truth for which eSIM profiles are available on this device. | 
 | class COMPONENT_EXPORT(CHROMEOS_NETWORK) CellularESimProfileHandler | 
 |     : public HermesManagerClient::Observer, | 
 |       public HermesEuiccClient::Observer, | 
 |       public HermesProfileClient::Observer { | 
 |  public: | 
 |   class Observer : public base::CheckedObserver { | 
 |    public: | 
 |     ~Observer() override = default; | 
 |  | 
 |     // Invoked when an eSIM profile is added, removed, or updated. | 
 |     virtual void OnESimProfileListUpdated() = 0; | 
 |   }; | 
 |  | 
 |   CellularESimProfileHandler(const CellularESimProfileHandler&) = delete; | 
 |   CellularESimProfileHandler& operator=(const CellularESimProfileHandler&) = | 
 |       delete; | 
 |   ~CellularESimProfileHandler() override; | 
 |  | 
 |   void Init(NetworkStateHandler* network_state_handler, | 
 |             CellularInhibitor* cellular_inhibitor); | 
 |  | 
 |   // Callback which returns an InhibitLock. If the InhibitLock returned by the | 
 |   // function is null, this means that the operation failed. | 
 |   using RefreshProfilesCallback = | 
 |       base::OnceCallback<void(std::unique_ptr<CellularInhibitor::InhibitLock>)>; | 
 |  | 
 |   // Callback which returns the result of requesting available profiles and all | 
 |   // available profiles that were discovered. | 
 |   using RequestAvailableProfilesCallback = | 
 |       base::OnceCallback<void(cellular_setup::mojom::ESimOperationResult, | 
 |                               std::vector<CellularESimProfile>)>; | 
 |  | 
 |   // Refreshes the list of installed profiles from Hermes. This operation | 
 |   // requires the Cellular Device to be inhibited. If |inhibit_lock| is passed | 
 |   // by the client, it will be used; otherwise, this function will acquire one | 
 |   // internally. The |RefreshProfileListAndRestoreSlot| variant is identical | 
 |   // except that it requests Hermes to maintain SIM slots after refresh. | 
 |   // | 
 |   // On success, this function returns the lock; on failure, it returns null. | 
 |   void RefreshProfileList( | 
 |       const dbus::ObjectPath& euicc_path, | 
 |       RefreshProfilesCallback callback, | 
 |       std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock = nullptr); | 
 |   void RefreshProfileListAndRestoreSlot( | 
 |       const dbus::ObjectPath& euicc_path, | 
 |       RefreshProfilesCallback callback, | 
 |       std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock = nullptr); | 
 |  | 
 |   // Requests the list of profiles that are available for installation from | 
 |   // known SM-DS servers. This operation will cause the cellular device to | 
 |   // become inhibited. The operation result provided to the callback indicates | 
 |   // whether this function was able to successfully inhibit the cellular device. | 
 |   virtual void RequestAvailableProfiles( | 
 |       const dbus::ObjectPath& euicc_path, | 
 |       RequestAvailableProfilesCallback callback); | 
 |  | 
 |   // Returns a list of the known cellular eSIM profiles fetched from Hermes. | 
 |   // Note that this function returns cached values if an eSIM slot is not active | 
 |   // (e.g., if ModemManager is currently pointed to a pSIM slot). | 
 |   virtual std::vector<CellularESimProfile> GetESimProfiles() = 0; | 
 |  | 
 |   // Returns whether profiles for the EUICC with the given EID or path have been | 
 |   // refreshsed. If this function returns true, any known eSIM profiles for the | 
 |   // associated EUICC should be returned by GetESimProfiles(). | 
 |   virtual bool HasRefreshedProfilesForEuicc(const std::string& eid) = 0; | 
 |   virtual bool HasRefreshedProfilesForEuicc( | 
 |       const dbus::ObjectPath& euicc_path) = 0; | 
 |  | 
 |   virtual void SetDevicePrefs(PrefService* device_prefs) = 0; | 
 |  | 
 |   void AddObserver(Observer* observer); | 
 |   void RemoveObserver(Observer* observer); | 
 |  | 
 |  protected: | 
 |   CellularESimProfileHandler(); | 
 |  | 
 |   bool has_completed_successful_profile_refresh() const { | 
 |     return has_completed_successful_profile_refresh_; | 
 |   } | 
 |  | 
 |   virtual void OnHermesPropertiesUpdated() = 0; | 
 |   void NotifyESimProfileListUpdated(); | 
 |  | 
 |   const NetworkStateHandler* network_state_handler() const { | 
 |     return network_state_handler_; | 
 |   } | 
 |  | 
 |   NetworkStateHandler* network_state_handler() { | 
 |     return network_state_handler_; | 
 |   } | 
 |  | 
 |   CellularInhibitor* cellular_inhibitor() const { return cellular_inhibitor_; } | 
 |  | 
 |   virtual void InitInternal() {} | 
 |  | 
 |  private: | 
 |   // Requesting profiles available to install requires performing operations | 
 |   // that must be done in serial. This struct is used to contain all of the | 
 |   // information necessary to perform these operations, collect the results | 
 |   // of each operation as it is completed, and to hold the callback that should | 
 |   // be invoked once all of the operations have been completed. | 
 |   struct RequestAvailableProfilesInfo { | 
 |     RequestAvailableProfilesInfo(); | 
 |     ~RequestAvailableProfilesInfo(); | 
 |  | 
 |     // The list of SM-DS activation codes that should be used to scan for | 
 |     // available profiles. | 
 |     std::vector<std::string> smds_activation_codes; | 
 |  | 
 |     // The list of paths to profiles found when scanning with activation codes | 
 |     // from |smds_activation_codes|. | 
 |     std::vector<dbus::ObjectPath> profile_paths; | 
 |  | 
 |     RequestAvailableProfilesCallback callback; | 
 |   }; | 
 |  | 
 |   // HermesManagerClient::Observer: | 
 |   void OnAvailableEuiccListChanged() override; | 
 |  | 
 |   // HermesEuiccClient::Observer: | 
 |   void OnEuiccPropertyChanged(const dbus::ObjectPath& euicc_path, | 
 |                               const std::string& property_name) override; | 
 |  | 
 |   // HermesProfileClient::Observer: | 
 |   void OnCarrierProfilePropertyChanged( | 
 |       const dbus::ObjectPath& carrier_profile_path, | 
 |       const std::string& property_name) override; | 
 |  | 
 |   void PerformRefreshProfileList( | 
 |       const dbus::ObjectPath& euicc_path, | 
 |       bool restore_slot, | 
 |       RefreshProfilesCallback callback, | 
 |       std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock = nullptr); | 
 |   void OnInhibitedForRefreshProfileList( | 
 |       const dbus::ObjectPath& euicc_path, | 
 |       bool restore_slot, | 
 |       RefreshProfilesCallback callback, | 
 |       std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock); | 
 |   void RefreshProfilesWithLock( | 
 |       const dbus::ObjectPath& euicc_path, | 
 |       bool restore_slot, | 
 |       RefreshProfilesCallback callback, | 
 |       std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock); | 
 |   void OnRequestInstalledProfilesResult(base::TimeTicks start_time, | 
 |                                         HermesResponseStatus status); | 
 |   void OnInhibitedForRequestAvailableProfiles( | 
 |       const dbus::ObjectPath& euicc_path, | 
 |       std::unique_ptr<RequestAvailableProfilesInfo> info, | 
 |       std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock); | 
 |   void PerformRequestAvailableProfiles( | 
 |       const dbus::ObjectPath& euicc_path, | 
 |       std::unique_ptr<RequestAvailableProfilesInfo> info, | 
 |       std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock); | 
 |   void OnRequestAvailableProfiles( | 
 |       const dbus::ObjectPath& euicc_path, | 
 |       std::unique_ptr<RequestAvailableProfilesInfo> info, | 
 |       std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock, | 
 |       const std::string& smds_activation_code, | 
 |       const base::TimeTicks start_time, | 
 |       HermesResponseStatus status, | 
 |       const std::vector<dbus::ObjectPath>& profile_paths); | 
 |   void CompleteRequestAvailableProfiles( | 
 |       const dbus::ObjectPath& euicc_path, | 
 |       std::unique_ptr<RequestAvailableProfilesInfo> info); | 
 |  | 
 |   raw_ptr<CellularInhibitor> cellular_inhibitor_ = nullptr; | 
 |  | 
 |   raw_ptr<NetworkStateHandler> network_state_handler_ = nullptr; | 
 |  | 
 |   base::ObserverList<Observer> observer_list_; | 
 |  | 
 |   // True if the profile list has been refreshed successfully during this | 
 |   // session. | 
 |   bool has_completed_successful_profile_refresh_ = false; | 
 |  | 
 |   // When a profile refresh is in progress, the inhibit lock. | 
 |   std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock_; | 
 |  | 
 |   // When a profile refresh is in progress, the callback. | 
 |   RefreshProfilesCallback callback_; | 
 |  | 
 |   base::WeakPtrFactory<CellularESimProfileHandler> weak_ptr_factory_{this}; | 
 | }; | 
 |  | 
 | }  // namespace ash | 
 |  | 
 | #endif  // CHROMEOS_ASH_COMPONENTS_NETWORK_CELLULAR_ESIM_PROFILE_HANDLER_H_ |