multidevice_feature_access_manager.cc 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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. #include "ash/components/phonehub/multidevice_feature_access_manager.h"
  5. #include "ash/components/multidevice/logging/logging.h"
  6. #include "base/bind.h"
  7. #include "base/memory/ptr_util.h"
  8. namespace ash {
  9. namespace phonehub {
  10. MultideviceFeatureAccessManager::MultideviceFeatureAccessManager() = default;
  11. MultideviceFeatureAccessManager::~MultideviceFeatureAccessManager() = default;
  12. std::unique_ptr<NotificationAccessSetupOperation>
  13. MultideviceFeatureAccessManager::AttemptNotificationSetup(
  14. NotificationAccessSetupOperation::Delegate* delegate) {
  15. // Should only be able to start the setup process if notification access is
  16. // available but not yet granted.
  17. // Legacy setup flow used when FeatureSetupRequest is not supported.
  18. if (GetNotificationAccessStatus() != AccessStatus::kAvailableButNotGranted)
  19. return nullptr;
  20. int operation_id = next_operation_id_;
  21. ++next_operation_id_;
  22. auto operation = base::WrapUnique(new NotificationAccessSetupOperation(
  23. delegate,
  24. base::BindOnce(
  25. &MultideviceFeatureAccessManager::OnNotificationSetupOperationDeleted,
  26. weak_ptr_factory_.GetWeakPtr(), operation_id)));
  27. id_to_notification_operation_map_.emplace(operation_id, operation.get());
  28. OnNotificationSetupRequested();
  29. return operation;
  30. }
  31. std::unique_ptr<CombinedAccessSetupOperation>
  32. MultideviceFeatureAccessManager::AttemptCombinedFeatureSetup(
  33. bool camera_roll,
  34. bool notifications,
  35. CombinedAccessSetupOperation::Delegate* delegate) {
  36. // New setup flow for combined Camera Roll and/or Notifications setup using
  37. // FeatureSetupRequest message type.
  38. if (!GetFeatureSetupRequestSupported()) {
  39. return nullptr;
  40. }
  41. if (GetCameraRollAccessStatus() != AccessStatus::kAvailableButNotGranted &&
  42. camera_roll) {
  43. return nullptr;
  44. }
  45. if (GetNotificationAccessStatus() != AccessStatus::kAvailableButNotGranted &&
  46. notifications) {
  47. return nullptr;
  48. }
  49. int operation_id = next_operation_id_;
  50. ++next_operation_id_;
  51. auto operation = base::WrapUnique(new CombinedAccessSetupOperation(
  52. delegate,
  53. base::BindOnce(
  54. &MultideviceFeatureAccessManager::OnCombinedSetupOperationDeleted,
  55. weak_ptr_factory_.GetWeakPtr(), operation_id)));
  56. id_to_combined_operation_map_.emplace(operation_id, operation.get());
  57. OnCombinedSetupRequested(camera_roll, notifications);
  58. return operation;
  59. }
  60. void MultideviceFeatureAccessManager::AddObserver(Observer* observer) {
  61. observer_list_.AddObserver(observer);
  62. }
  63. void MultideviceFeatureAccessManager::RemoveObserver(Observer* observer) {
  64. observer_list_.RemoveObserver(observer);
  65. }
  66. void MultideviceFeatureAccessManager::NotifyNotificationAccessChanged() {
  67. for (auto& observer : observer_list_)
  68. observer.OnNotificationAccessChanged();
  69. }
  70. void MultideviceFeatureAccessManager::NotifyCameraRollAccessChanged() {
  71. for (auto& observer : observer_list_)
  72. observer.OnCameraRollAccessChanged();
  73. }
  74. void MultideviceFeatureAccessManager::NotifyAppsAccessChanged() {
  75. for (auto& observer : observer_list_)
  76. observer.OnAppsAccessChanged();
  77. }
  78. void MultideviceFeatureAccessManager::
  79. NotifyFeatureSetupRequestSupportedChanged() {
  80. for (auto& observer : observer_list_)
  81. observer.OnFeatureSetupRequestSupportedChanged();
  82. }
  83. void MultideviceFeatureAccessManager::SetNotificationSetupOperationStatus(
  84. NotificationAccessSetupOperation::Status new_status) {
  85. DCHECK(IsNotificationSetupOperationInProgress());
  86. PA_LOG(INFO) << "Notification access setup flow - new status: " << new_status;
  87. for (auto& it : id_to_notification_operation_map_)
  88. it.second->NotifyNotificationStatusChanged(new_status);
  89. if (NotificationAccessSetupOperation::IsFinalStatus(new_status))
  90. id_to_notification_operation_map_.clear();
  91. }
  92. bool MultideviceFeatureAccessManager::IsNotificationSetupOperationInProgress()
  93. const {
  94. return !id_to_notification_operation_map_.empty();
  95. }
  96. void MultideviceFeatureAccessManager::OnNotificationSetupOperationDeleted(
  97. int operation_id) {
  98. auto it = id_to_notification_operation_map_.find(operation_id);
  99. if (it == id_to_notification_operation_map_.end())
  100. return;
  101. id_to_notification_operation_map_.erase(it);
  102. if (id_to_notification_operation_map_.empty())
  103. PA_LOG(INFO) << "Notification access setup operation has ended.";
  104. }
  105. void MultideviceFeatureAccessManager::SetCombinedSetupOperationStatus(
  106. CombinedAccessSetupOperation::Status new_status) {
  107. DCHECK(IsCombinedSetupOperationInProgress());
  108. PA_LOG(INFO) << "Combined access setup flow - new status: " << new_status;
  109. for (auto& it : id_to_combined_operation_map_)
  110. it.second->NotifyCombinedStatusChanged(new_status);
  111. if (CombinedAccessSetupOperation::IsFinalStatus(new_status))
  112. id_to_combined_operation_map_.clear();
  113. }
  114. bool MultideviceFeatureAccessManager::IsCombinedSetupOperationInProgress()
  115. const {
  116. return !id_to_combined_operation_map_.empty();
  117. }
  118. void MultideviceFeatureAccessManager::OnNotificationSetupRequested() {}
  119. void MultideviceFeatureAccessManager::OnCombinedSetupRequested(
  120. bool camera_roll,
  121. bool notifications) {}
  122. void MultideviceFeatureAccessManager::OnCombinedSetupOperationDeleted(
  123. int operation_id) {
  124. auto it = id_to_combined_operation_map_.find(operation_id);
  125. if (it == id_to_combined_operation_map_.end())
  126. return;
  127. id_to_combined_operation_map_.erase(it);
  128. if (id_to_combined_operation_map_.empty())
  129. PA_LOG(INFO) << "Combined access setup operation has ended.";
  130. }
  131. void MultideviceFeatureAccessManager::Observer::OnNotificationAccessChanged() {
  132. // Optional method, inherit class doesn't have to implement this
  133. }
  134. void MultideviceFeatureAccessManager::Observer::OnCameraRollAccessChanged() {
  135. // Optional method, inherit class doesn't have to implement this
  136. }
  137. void MultideviceFeatureAccessManager::Observer::OnAppsAccessChanged() {
  138. // Optional method, inherit class doesn't have to implement this
  139. }
  140. void MultideviceFeatureAccessManager::Observer::
  141. OnFeatureSetupRequestSupportedChanged() {
  142. // Optional method, inherit class doesn't have to implement this
  143. }
  144. std::ostream& operator<<(std::ostream& stream,
  145. MultideviceFeatureAccessManager::AccessStatus status) {
  146. switch (status) {
  147. case MultideviceFeatureAccessManager::AccessStatus::kProhibited:
  148. stream << "[Access prohibited]";
  149. break;
  150. case MultideviceFeatureAccessManager::AccessStatus::kAvailableButNotGranted:
  151. stream << "[Access available but not granted]";
  152. break;
  153. case MultideviceFeatureAccessManager::AccessStatus::kAccessGranted:
  154. stream << "[Access granted]";
  155. break;
  156. }
  157. return stream;
  158. }
  159. std::ostream& operator<<(
  160. std::ostream& stream,
  161. MultideviceFeatureAccessManager::AccessProhibitedReason reason) {
  162. switch (reason) {
  163. case MultideviceFeatureAccessManager::AccessProhibitedReason::kUnknown:
  164. stream << "[Unknown]";
  165. break;
  166. case MultideviceFeatureAccessManager::AccessProhibitedReason::kWorkProfile:
  167. stream << "[Work Profile]";
  168. break;
  169. case MultideviceFeatureAccessManager::AccessProhibitedReason::
  170. kDisabledByPhonePolicy:
  171. stream << "[Admin Policy]";
  172. break;
  173. }
  174. return stream;
  175. }
  176. std::ostream& operator<<(
  177. std::ostream& stream,
  178. std::pair<MultideviceFeatureAccessManager::AccessStatus,
  179. MultideviceFeatureAccessManager::AccessProhibitedReason>
  180. status_reason) {
  181. stream << status_reason.first;
  182. if (status_reason.first ==
  183. MultideviceFeatureAccessManager::AccessStatus::kProhibited) {
  184. stream << "," << status_reason.second;
  185. }
  186. return stream;
  187. }
  188. } // namespace phonehub
  189. } // namespace ash