1 // Copyright 2017 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 COMPONENTS_UKM_OBSERVERS_UKM_CONSENT_STATE_OBSERVER_H_ 6 #define COMPONENTS_UKM_OBSERVERS_UKM_CONSENT_STATE_OBSERVER_H_ 7 8 #include <map> 9 10 #include "base/scoped_observer.h" 11 #include "components/sync/driver/sync_service.h" 12 #include "components/sync/driver/sync_service_observer.h" 13 #include "components/unified_consent/url_keyed_data_collection_consent_helper.h" 14 15 class PrefService; 16 17 namespace ukm { 18 19 // Observer that monitors whether UKM is allowed for all profiles. 20 // 21 // For one profile, UKM is allowed iff URL-keyed anonymized data collection is 22 // enabled. 23 class UkmConsentStateObserver 24 : public syncer::SyncServiceObserver, 25 public unified_consent::UrlKeyedDataCollectionConsentHelper::Observer { 26 public: 27 UkmConsentStateObserver(); 28 ~UkmConsentStateObserver() override; 29 30 // Starts observing whether UKM is allowed for a profile. 31 // |pref_service| is the pref service of a profile. 32 void StartObserving(syncer::SyncService* sync_service, 33 PrefService* pref_service); 34 35 // Returns true iff all UKM is allowed for all profile states. This means that 36 // URL-keyed anonymized data collection is enabled for all profiles. 37 virtual bool IsUkmAllowedForAllProfiles(); 38 39 // Returns true iff sync is in a state that allows UKM to capture extensions. 40 // This means that all profiles have EXTENSIONS data type enabled for syncing. 41 virtual bool IsUkmAllowedWithExtensionsForAllProfiles(); 42 43 protected: 44 // Called after UKM consent state changed. 45 // If |must_purge| is true, the UKM is not allowed for some profile, and local 46 // data must be purged. 47 virtual void OnUkmAllowedStateChanged(bool must_purge) = 0; 48 49 private: 50 // syncer::SyncServiceObserver: 51 void OnStateChanged(syncer::SyncService* sync) override; 52 void OnSyncShutdown(syncer::SyncService* sync) override; 53 54 // unified_consent::UrlKeyedDataCollectionConsentHelper::Observer: 55 void OnUrlKeyedDataCollectionConsentStateChanged( 56 unified_consent::UrlKeyedDataCollectionConsentHelper* consent_helper) 57 override; 58 59 // Recomputes |ukm_allowed_for_all_profiles_| and 60 // |ukm_allowed_with_extensions_for_all_profiles_| from |previous_states_|; 61 void UpdateUkmAllowedForAllProfiles(bool must_purge); 62 63 // Returns true iff all profile states in |previous_states_| allow UKM. 64 // If there are no profiles being observed, this returns false. 65 bool CheckPreviousStatesAllowUkm(); 66 67 // Returns true iff all profile states in |previous_states_| allow extension 68 // UKM. If there are no profiles are being observed, this returns false. 69 bool CheckPreviousStatesAllowExtensionUkm(); 70 71 // Tracks observed sync services, for cleanup. 72 ScopedObserver<syncer::SyncService, syncer::SyncServiceObserver> 73 sync_observer_; 74 75 // State data about profiles that we need to remember. 76 struct ProfileState { 77 // Returns true if this state allows UKM (i.e. URL-keyed anonymized 78 // data collection is enabled). 79 bool AllowsUkm() const; 80 81 // Returns true if |AllowsUkm| and if sync extensions are enabled. 82 bool AllowsUkmWithExtension() const; 83 84 // Whether anonymized data collection is enabled. 85 bool anonymized_data_collection_enabled = false; 86 87 // If the user has extension sync enabled. 88 bool extensions_enabled = false; 89 }; 90 91 // Updates the UKM enabled state for a profile and then triggers an update of 92 // the state for all profiles. 93 // |sync| and |consent_helper| must not be null. 94 void UpdateProfileState( 95 syncer::SyncService* sync, 96 unified_consent::UrlKeyedDataCollectionConsentHelper* consent_helper); 97 98 // Gets the current state of a profile. 99 // |sync| and |consent_helper| must not be null. 100 static ProfileState GetProfileState( 101 syncer::SyncService* sync, 102 unified_consent::UrlKeyedDataCollectionConsentHelper* consent_helper); 103 104 // The state of the profile being observed. 105 // 106 // Note: UKM consent does not rely on sync but there must be exactly one 107 // sync service per profile, so it is safe to key the profile states by the 108 // sync service. 109 std::map<syncer::SyncService*, ProfileState> previous_states_; 110 111 // The list of URL-keyed anonymized data collection consent helpers. 112 // 113 // Note: UrlKeyedDataCollectionConsentHelper does not rely on sync but there 114 // must be exactly one per Chromium profile. As there is a single sync service 115 // per profile, it is safe to key them by sync service instead of introducing 116 // an additional map. 117 std::map< 118 syncer::SyncService*, 119 std::unique_ptr<unified_consent::UrlKeyedDataCollectionConsentHelper>> 120 consent_helpers_; 121 122 // Tracks if UKM is allowed on all profiles after the last state change. 123 bool ukm_allowed_for_all_profiles_ = false; 124 125 // Tracks if extension sync was enabled on all profiles after the last state 126 // change. 127 bool ukm_allowed_with_extensions_for_all_profiles_ = false; 128 129 DISALLOW_COPY_AND_ASSIGN(UkmConsentStateObserver); 130 }; 131 132 } // namespace ukm 133 134 #endif // COMPONENTS_UKM_OBSERVERS_UKM_CONSENT_STATE_OBSERVER_H_ 135