1 // Copyright 2014 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 CHROME_BROWSER_SIGNIN_EASY_UNLOCK_SERVICE_H_ 6 #define CHROME_BROWSER_SIGNIN_EASY_UNLOCK_SERVICE_H_ 7 8 #include <set> 9 #include <string> 10 11 #include "base/macros.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/weak_ptr.h" 14 #include "base/observer_list.h" 15 #include "chrome/browser/signin/easy_unlock_screenlock_state_handler.h" 16 #include "components/keyed_service/core/keyed_service.h" 17 18 #if defined(OS_CHROMEOS) 19 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_types.h" 20 #endif 21 22 namespace base { 23 class DictionaryValue; 24 class ListValue; 25 } 26 27 namespace user_manager { 28 class User; 29 } 30 31 namespace user_prefs { 32 class PrefRegistrySyncable; 33 } 34 35 class EasyUnlockAuthAttempt; 36 class EasyUnlockServiceObserver; 37 class Profile; 38 class PrefRegistrySimple; 39 40 class EasyUnlockService : public KeyedService { 41 public: 42 enum TurnOffFlowStatus { 43 IDLE, 44 PENDING, 45 FAIL, 46 }; 47 48 enum Type { 49 TYPE_REGULAR, 50 TYPE_SIGNIN 51 }; 52 53 // Gets EasyUnlockService instance. 54 static EasyUnlockService* Get(Profile* profile); 55 56 // Gets EasyUnlockService instance associated with a user if the user is 57 // logged in and his profile is initialized. 58 static EasyUnlockService* GetForUser(const user_manager::User& user); 59 60 // Registers Easy Unlock profile preferences. 61 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); 62 63 // Registers Easy Unlock local state entries. 64 static void RegisterPrefs(PrefRegistrySimple* registry); 65 66 // Removes the hardlock state for the given user. 67 static void ResetLocalStateForUser(const std::string& user_id); 68 69 // Returns true if Easy sign-in is enabled. 70 static bool IsSignInEnabled(); 71 72 // Returns the EasyUnlockService type. 73 virtual Type GetType() const = 0; 74 75 // Returns the user currently associated with the service. 76 virtual std::string GetUserEmail() const = 0; 77 78 // Launches Easy Unlock Setup app. 79 virtual void LaunchSetup() = 0; 80 81 // Gets/Sets/Clears the permit access for the local device. 82 virtual const base::DictionaryValue* GetPermitAccess() const = 0; 83 virtual void SetPermitAccess(const base::DictionaryValue& permit) = 0; 84 virtual void ClearPermitAccess() = 0; 85 86 // Gets/Sets/Clears the remote devices list. 87 virtual const base::ListValue* GetRemoteDevices() const = 0; 88 virtual void SetRemoteDevices(const base::ListValue& devices) = 0; 89 virtual void ClearRemoteDevices() = 0; 90 91 // Runs the flow for turning Easy unlock off. 92 virtual void RunTurnOffFlow() = 0; 93 94 // Resets the turn off flow if one is in progress. 95 virtual void ResetTurnOffFlow() = 0; 96 97 // Returns the current turn off flow status. 98 virtual TurnOffFlowStatus GetTurnOffFlowStatus() const = 0; 99 100 // Gets the challenge bytes for the user currently associated with the 101 // service. 102 virtual std::string GetChallenge() const = 0; 103 104 // Retrieved wrapped secret that should be used to unlock cryptohome for the 105 // user currently associated with the service. If the service does not support 106 // signin (i.e. service for a regular profile) or there is no secret available 107 // for the user, returns an empty string. 108 virtual std::string GetWrappedSecret() const = 0; 109 110 // Records metrics for Easy sign-in outcome for the given user. 111 virtual void RecordEasySignInOutcome(const std::string& user_id, 112 bool success) const = 0; 113 114 // Records metrics for password based flow for the given user. 115 virtual void RecordPasswordLoginEvent(const std::string& user_id) const = 0; 116 117 // Whether easy unlock is allowed to be used. If the controlling preference 118 // is set (from policy), this returns the preference value. Otherwise, it is 119 // permitted either the flag is enabled or its field trial is enabled. 120 bool IsAllowed(); 121 122 // Sets the hardlock state for the associated user. 123 void SetHardlockState(EasyUnlockScreenlockStateHandler::HardlockState state); 124 125 // Returns the hardlock state for the associated user. 126 EasyUnlockScreenlockStateHandler::HardlockState GetHardlockState() const; 127 128 // Gets the persisted hardlock state. Return true if there is persisted 129 // hardlock state and the value would be set to |state|. Otherwise, 130 // returns false and |state| is unchanged. 131 bool GetPersistedHardlockState( 132 EasyUnlockScreenlockStateHandler::HardlockState* state) const; 133 134 // Shows the hardlock or connecting state as initial UI before cryptohome 135 // keys checking and state update from the app. 136 void ShowInitialUserState(); 137 138 // Updates the user pod on the signin/lock screen for the user associated with 139 // the service to reflect the provided screenlock state. 140 bool UpdateScreenlockState(EasyUnlockScreenlockStateHandler::State state); 141 142 // Starts an auth attempt for the user associated with the service. The 143 // attempt type (unlock vs. signin) will depend on the service type. 144 void AttemptAuth(const std::string& user_id); 145 146 // Finalizes the previously started auth attempt for easy unlock. If called on 147 // signin profile service, it will cancel the current auth attempt if one 148 // exists. 149 void FinalizeUnlock(bool success); 150 151 // Finalizes previously started auth attempt for easy signin. If called on 152 // regular profile service, it will cancel the current auth attempt if one 153 // exists. 154 void FinalizeSignin(const std::string& secret); 155 156 // Checks the consistency between pairing data and cryptohome keys. Set 157 // hardlock state if the two do not match. 158 void CheckCryptohomeKeysAndMaybeHardlock(); 159 160 // Marks the Easy Unlock screen lock state as the one associated with the 161 // trial run initiated by Easy Unlock app. 162 void SetTrialRun(); 163 164 void AddObserver(EasyUnlockServiceObserver* observer); 165 void RemoveObserver(EasyUnlockServiceObserver* observer); 166 167 protected: 168 explicit EasyUnlockService(Profile* profile); 169 virtual ~EasyUnlockService(); 170 171 // Does a service type specific initialization. 172 virtual void InitializeInternal() = 0; 173 174 // Does a service type specific shutdown. Called from |Shutdown|. 175 virtual void ShutdownInternal() = 0; 176 177 // Service type specific tests for whether the service is allowed. Returns 178 // false if service is not allowed. If true is returned, the service may still 179 // not be allowed if common tests fail (e.g. if Bluetooth is not available). 180 virtual bool IsAllowedInternal() = 0; 181 182 // KeyedService override: 183 virtual void Shutdown() OVERRIDE; 184 185 // Exposes the profile to which the service is attached to subclasses. 186 Profile* profile() const { return profile_; } 187 188 // Installs the Easy unlock component app if it isn't installed and enables 189 // the app if it is disabled. 190 void LoadApp(); 191 192 // Disables the Easy unlock component app if it's loaded. 193 void DisableAppIfLoaded(); 194 195 // Unloads the Easy unlock component app if it's loaded. 196 void UnloadApp(); 197 198 // Reloads the Easy unlock component app if it's loaded. 199 void ReloadApp(); 200 201 // Checks whether Easy unlock should be running and updates app state. 202 void UpdateAppState(); 203 204 // Notifies the easy unlock app that the user state has been updated. 205 void NotifyUserUpdated(); 206 207 // Notifies observers that the turn off flow status changed. 208 void NotifyTurnOffOperationStatusChanged(); 209 210 // Resets the screenlock state set by this service. 211 void ResetScreenlockState(); 212 213 // Updates |screenlock_state_handler_|'s hardlocked state. 214 void SetScreenlockHardlockedState( 215 EasyUnlockScreenlockStateHandler::HardlockState state); 216 217 const EasyUnlockScreenlockStateHandler* screenlock_state_handler() const { 218 return screenlock_state_handler_.get(); 219 } 220 221 // Saves hardlock state for the given user. Update UI if the currently 222 // associated user is the same. 223 void SetHardlockStateForUser( 224 const std::string& user_id, 225 EasyUnlockScreenlockStateHandler::HardlockState state); 226 227 private: 228 // A class to detect whether a bluetooth adapter is present. 229 class BluetoothDetector; 230 231 // Initializes the service after ExtensionService is ready. 232 void Initialize(); 233 234 // Gets |screenlock_state_handler_|. Returns NULL if Easy Unlock is not 235 // allowed. Otherwise, if |screenlock_state_handler_| is not set, an instance 236 // is created. Do not cache the returned value, as it may go away if Easy 237 // Unlock gets disabled. 238 EasyUnlockScreenlockStateHandler* GetScreenlockStateHandler(); 239 240 // Callback when Bluetooth adapter present state changes. 241 void OnBluetoothAdapterPresentChanged(); 242 243 #if defined(OS_CHROMEOS) 244 // Callback for get key operation from CheckCryptohomeKeysAndMaybeHardlock. 245 void OnCryptohomeKeysFetchedForChecking( 246 const std::string& user_id, 247 const std::set<std::string> paired_devices, 248 bool success, 249 const chromeos::EasyUnlockDeviceKeyDataList& key_data_list); 250 #endif 251 252 // Updates the service to state for handling system suspend. 253 void PrepareForSuspend(); 254 255 Profile* profile_; 256 257 // Created lazily in |GetScreenlockStateHandler|. 258 scoped_ptr<EasyUnlockScreenlockStateHandler> screenlock_state_handler_; 259 260 // The handler for the current auth attempt. Set iff an auth attempt is in 261 // progress. 262 scoped_ptr<EasyUnlockAuthAttempt> auth_attempt_; 263 264 scoped_ptr<BluetoothDetector> bluetooth_detector_; 265 266 #if defined(OS_CHROMEOS) 267 // Monitors suspend and wake state of ChromeOS. 268 class PowerMonitor; 269 scoped_ptr<PowerMonitor> power_monitor_; 270 #endif 271 272 // Whether the service has been shut down. 273 bool shut_down_; 274 275 ObserverList<EasyUnlockServiceObserver> observers_; 276 277 base::WeakPtrFactory<EasyUnlockService> weak_ptr_factory_; 278 279 DISALLOW_COPY_AND_ASSIGN(EasyUnlockService); 280 }; 281 282 #endif // CHROME_BROWSER_SIGNIN_EASY_UNLOCK_SERVICE_H_ 283