multidevice_feature_access_manager.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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. #ifndef ASH_COMPONENTS_PHONEHUB_MULTIDEVICE_FEATURE_ACCESS_MANAGER_H_
  5. #define ASH_COMPONENTS_PHONEHUB_MULTIDEVICE_FEATURE_ACCESS_MANAGER_H_
  6. #include <ostream>
  7. #include "ash/components/phonehub/combined_access_setup_operation.h"
  8. #include "ash/components/phonehub/feature_setup_response_processor.h"
  9. #include "ash/components/phonehub/notification_access_setup_operation.h"
  10. #include "ash/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h"
  11. #include "base/containers/flat_map.h"
  12. #include "base/memory/weak_ptr.h"
  13. #include "base/observer_list.h"
  14. #include "base/observer_list_types.h"
  15. namespace ash {
  16. namespace phonehub {
  17. // Tracks the status of whether the user has granted permissions for the
  18. // following features to be enabled on the host device:
  19. // 1. Notification
  20. // 2. Camera roll
  21. //
  22. // While Phone Hub can be enabled via Chrome OS, access to
  23. // notifications requires that the user grant access via Android settings. If a
  24. // Phone Hub connection to the phone has never succeeded, we assume that access
  25. // has not yet been granted. If there is no active Phone Hub connection, we
  26. // assume that the last access value seen is the current value.
  27. //
  28. // This class provides two methods for requesting access permissions on the
  29. // connected Android device:
  30. //
  31. // AttemptNotificationSetup() is the legacy setup flow that only supports setup
  32. // of the Notifications feature.
  33. //
  34. // AttemptCombinedFeatureSetup() is the new setup flow that supports the
  35. // Notifications and/or Camera Roll features. New features requiring setup
  36. // should be added to this method's flow.
  37. class MultideviceFeatureAccessManager {
  38. public:
  39. // Status of a feature's access. Numerical values are stored in prefs and
  40. // should not be changed or reused.
  41. enum class AccessStatus {
  42. // Access has not been granted and is prohibited from being granted (e.g.,
  43. // if the phone is using a Work Profile when trying to use notification
  44. // fearture).
  45. kProhibited = 0,
  46. // Access has not been granted, but the user is free to grant access.
  47. kAvailableButNotGranted = 1,
  48. // Access has been granted by the user.
  49. kAccessGranted = 2
  50. };
  51. enum class AccessProhibitedReason {
  52. // Access is either not prohibited or is unset. Use as a safe default value.
  53. kUnknown = 0,
  54. // Access is prohibited because the phone is using a Work Profile and on
  55. // Android version <N.
  56. kWorkProfile = 1,
  57. // Access is prohibited because the phone is using a Work Profile, and the
  58. // policy managing the phone disables access.
  59. kDisabledByPhonePolicy = 2
  60. };
  61. class Observer : public base::CheckedObserver {
  62. public:
  63. ~Observer() override = default;
  64. // Called when notification access has changed; use
  65. // GetNotificationAccessStatus() for the new status.
  66. virtual void OnNotificationAccessChanged();
  67. // Called when camera roll access has changed; use
  68. // GetCameraRollAccessStatus() for the new status.
  69. virtual void OnCameraRollAccessChanged();
  70. // Called when apps access has changed; use
  71. // GetAppsAccessStatus() for the new status.
  72. virtual void OnAppsAccessChanged();
  73. // Called when FeatureSetupRequestSupported has changed; use
  74. // GetFeatureSetupRequestSupported() for the new status.
  75. virtual void OnFeatureSetupRequestSupportedChanged();
  76. };
  77. MultideviceFeatureAccessManager(MultideviceFeatureAccessManager&) = delete;
  78. MultideviceFeatureAccessManager& operator=(MultideviceFeatureAccessManager&) =
  79. delete;
  80. virtual ~MultideviceFeatureAccessManager();
  81. virtual AccessStatus GetNotificationAccessStatus() const = 0;
  82. virtual AccessStatus GetCameraRollAccessStatus() const = 0;
  83. virtual AccessStatus GetAppsAccessStatus() const = 0;
  84. // Return true if the feature status is ready for requesting access. If the
  85. // feature requires further access permission from phone side, we shouldn't
  86. // send out the access request until the feature state is fuly synced.
  87. virtual bool IsAccessRequestAllowed(
  88. multidevice_setup::mojom::Feature feature) = 0;
  89. virtual bool GetFeatureSetupRequestSupported() const = 0;
  90. // Returns the reason notification access status is prohibited. The return
  91. // result is valid if the current access status (from GetAccessStatus())
  92. // is AccessStatus::kProhibited. Otherwise, the result is undefined and should
  93. // not be used.
  94. virtual AccessProhibitedReason GetNotificationAccessProhibitedReason()
  95. const = 0;
  96. virtual bool HasMultideviceFeatureSetupUiBeenDismissed() const = 0;
  97. // Disables the ability to show the banner within the PhoneHub UI.
  98. virtual void DismissSetupRequiredUi() = 0;
  99. // Starts an attempt to enable the notification access. |delegate| will be
  100. // updated with the status of the flow as long as the operation object
  101. // returned by this function remains instantiated.
  102. //
  103. // To cancel an ongoing setup attempt, delete the operation. If a setup
  104. // attempt fails, clients can retry by calling AttemptNotificationSetup()
  105. // again to start a new attempt.
  106. //
  107. // If notification access has already been granted, this function returns null
  108. // since there is nothing to set up.
  109. std::unique_ptr<NotificationAccessSetupOperation> AttemptNotificationSetup(
  110. NotificationAccessSetupOperation::Delegate* delegate);
  111. // Starts an attempt to enable the access for multiple features. |delegate|
  112. // will be updated with the status of the flow as long as the operation object
  113. // returned by this function remains instantiated.
  114. //
  115. // To cancel an ongoing setup attempt, delete the operation. If a setup
  116. // attempt fails, clients can retry by calling AttemptCombinedFeatureSetup()
  117. // again to start a new attempt.
  118. //
  119. // If a requested feature's access has already been granted, or the
  120. // FeatureSetupRequest message is not supported on the phone, this function
  121. // returns null.
  122. std::unique_ptr<CombinedAccessSetupOperation> AttemptCombinedFeatureSetup(
  123. bool camera_roll,
  124. bool notifications,
  125. CombinedAccessSetupOperation::Delegate* delegate);
  126. void AddObserver(Observer* observer);
  127. void RemoveObserver(Observer* observer);
  128. protected:
  129. MultideviceFeatureAccessManager();
  130. void NotifyNotificationAccessChanged();
  131. void NotifyCameraRollAccessChanged();
  132. void NotifyAppsAccessChanged();
  133. void NotifyFeatureSetupRequestSupportedChanged();
  134. void SetNotificationSetupOperationStatus(
  135. NotificationAccessSetupOperation::Status new_status);
  136. void SetCombinedSetupOperationStatus(
  137. CombinedAccessSetupOperation::Status new_status);
  138. bool IsNotificationSetupOperationInProgress() const;
  139. bool IsCombinedSetupOperationInProgress() const;
  140. virtual void OnNotificationSetupRequested();
  141. virtual void OnCombinedSetupRequested(bool camera_roll, bool notifications);
  142. private:
  143. friend class MultideviceFeatureAccessManagerImplTest;
  144. friend class PhoneStatusProcessor;
  145. friend class FeatureSetupResponseProcessor;
  146. // Sets the internal AccessStatus but does not send a request for
  147. // a new status to the remote phone device.
  148. virtual void SetNotificationAccessStatusInternal(
  149. AccessStatus access_status,
  150. AccessProhibitedReason reason) = 0;
  151. // Sets the internal AccessStatus but does not send a request for
  152. // a new status to the remote phone device.
  153. virtual void SetCameraRollAccessStatusInternal(
  154. AccessStatus access_status) = 0;
  155. // Sets internal status tracking if feature setup request message is
  156. // supported by connected phone.
  157. virtual void SetFeatureSetupRequestSupportedInternal(bool supported) = 0;
  158. void OnNotificationSetupOperationDeleted(int operation_id);
  159. void OnCombinedSetupOperationDeleted(int operation_id);
  160. int next_operation_id_ = 0;
  161. base::flat_map<int, NotificationAccessSetupOperation*>
  162. id_to_notification_operation_map_;
  163. base::flat_map<int, CombinedAccessSetupOperation*>
  164. id_to_combined_operation_map_;
  165. base::ObserverList<Observer> observer_list_;
  166. base::WeakPtrFactory<MultideviceFeatureAccessManager> weak_ptr_factory_{this};
  167. };
  168. std::ostream& operator<<(std::ostream& stream,
  169. MultideviceFeatureAccessManager::AccessStatus status);
  170. std::ostream& operator<<(
  171. std::ostream& stream,
  172. MultideviceFeatureAccessManager::AccessProhibitedReason reason);
  173. std::ostream& operator<<(
  174. std::ostream& stream,
  175. std::pair<MultideviceFeatureAccessManager::AccessStatus,
  176. MultideviceFeatureAccessManager::AccessProhibitedReason>
  177. status_reason);
  178. } // namespace phonehub
  179. } // namespace ash
  180. // TODO(https://crbug.com/1164001): remove after the migration is finished.
  181. namespace chromeos {
  182. namespace phonehub {
  183. using ::ash::phonehub::MultideviceFeatureAccessManager;
  184. }
  185. } // namespace chromeos
  186. #endif // ASH_COMPONENTS_PHONEHUB_MULTIDEVICE_FEATURE_ACCESS_MANAGER_H_