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.
5 #ifndef CHROME_BROWSER_SIGNIN_EASY_UNLOCK_SERVICE_H_
6 #define CHROME_BROWSER_SIGNIN_EASY_UNLOCK_SERVICE_H_
11 #include "base/callback_forward.h"
12 #include "base/macros.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/observer_list.h"
16 #include "chrome/browser/signin/chrome_proximity_auth_client.h"
17 #include "chrome/browser/signin/easy_unlock_auth_attempt.h"
18 #include "chrome/browser/signin/easy_unlock_metrics.h"
19 #include "chrome/browser/signin/easy_unlock_screenlock_state_handler.h"
20 #include "components/keyed_service/core/keyed_service.h"
21 #include "components/proximity_auth/screenlock_state.h"
22 #include "components/proximity_auth/webui/proximity_auth_ui_delegate.h"
24 #if defined(OS_CHROMEOS)
25 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_types.h"
29 class DictionaryValue
;
33 namespace user_manager
{
37 namespace user_prefs
{
38 class PrefRegistrySyncable
;
41 namespace proximity_auth
{
42 class ProximityAuthBleSystem
;
45 class EasyUnlockAppManager
;
46 class EasyUnlockServiceObserver
;
48 class PrefRegistrySimple
;
50 class EasyUnlockService
: public KeyedService
,
51 public proximity_auth::ProximityAuthUIDelegate
{
53 enum TurnOffFlowStatus
{
64 // Easy Unlock settings that the user can configure.
69 // Whether to require the remote device to be in very close proximity
70 // before allowing unlock (~1 feet).
71 bool require_close_proximity
;
74 // Gets EasyUnlockService instance.
75 static EasyUnlockService
* Get(Profile
* profile
);
77 // Gets EasyUnlockService instance associated with a user if the user is
78 // logged in and his profile is initialized.
79 static EasyUnlockService
* GetForUser(const user_manager::User
& user
);
81 // Registers Easy Unlock profile preferences.
82 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable
* registry
);
84 // Registers Easy Unlock local state entries.
85 static void RegisterPrefs(PrefRegistrySimple
* registry
);
87 // Removes the hardlock state for the given user.
88 static void ResetLocalStateForUser(const std::string
& user_id
);
90 // Returns the user's preferences.
91 static UserSettings
GetUserSettings(const std::string
& user_id
);
93 // Returns the identifier for the device.
94 static std::string
GetDeviceId();
96 // Returns true if Easy sign-in is enabled.
97 static bool IsSignInEnabled();
99 // Returns the EasyUnlockService type.
100 virtual Type
GetType() const = 0;
102 // Returns the user currently associated with the service.
103 virtual std::string
GetUserEmail() const = 0;
105 // Launches Easy Unlock setup app.
106 virtual void LaunchSetup() = 0;
108 // Gets/Sets/Clears the permit access for the local device.
109 virtual const base::DictionaryValue
* GetPermitAccess() const = 0;
110 virtual void SetPermitAccess(const base::DictionaryValue
& permit
) = 0;
111 virtual void ClearPermitAccess() = 0;
113 // Gets/Sets the remote devices list.
114 virtual const base::ListValue
* GetRemoteDevices() const = 0;
115 virtual void SetRemoteDevices(const base::ListValue
& devices
) = 0;
117 // Runs the flow for turning Easy unlock off.
118 virtual void RunTurnOffFlow() = 0;
120 // Resets the turn off flow if one is in progress.
121 virtual void ResetTurnOffFlow() = 0;
123 // Returns the current turn off flow status.
124 virtual TurnOffFlowStatus
GetTurnOffFlowStatus() const = 0;
126 // Gets the challenge bytes for the user currently associated with the
128 virtual std::string
GetChallenge() const = 0;
130 // Retrieved wrapped secret that should be used to unlock cryptohome for the
131 // user currently associated with the service. If the service does not support
132 // signin (i.e. service for a regular profile) or there is no secret available
133 // for the user, returns an empty string.
134 virtual std::string
GetWrappedSecret() const = 0;
136 // Records metrics for Easy sign-in outcome for the given user.
137 virtual void RecordEasySignInOutcome(const std::string
& user_id
,
138 bool success
) const = 0;
140 // Records metrics for password based flow for the given user.
141 virtual void RecordPasswordLoginEvent(const std::string
& user_id
) const = 0;
143 // Starts auto pairing.
144 typedef base::Callback
<void(bool success
, const std::string
& error
)>
145 AutoPairingResultCallback
;
146 virtual void StartAutoPairing(const AutoPairingResultCallback
& callback
) = 0;
148 // Sets auto pairing result.
149 virtual void SetAutoPairingResult(bool success
, const std::string
& error
) = 0;
151 // Sets the service up and schedules service initialization.
152 void Initialize(scoped_ptr
<EasyUnlockAppManager
> app_manager
);
154 // Whether easy unlock is allowed to be used. If the controlling preference
155 // is set (from policy), this returns the preference value. Otherwise, it is
156 // permitted if the flag is enabled.
157 bool IsAllowed() const;
159 // Whether Easy Unlock is currently enabled for this user.
160 bool IsEnabled() const;
162 // Sets the hardlock state for the associated user.
163 void SetHardlockState(EasyUnlockScreenlockStateHandler::HardlockState state
);
165 // Returns the hardlock state for the associated user.
166 EasyUnlockScreenlockStateHandler::HardlockState
GetHardlockState() const;
168 // Gets the persisted hardlock state. Return true if there is persisted
169 // hardlock state and the value would be set to |state|. Otherwise,
170 // returns false and |state| is unchanged.
171 bool GetPersistedHardlockState(
172 EasyUnlockScreenlockStateHandler::HardlockState
* state
) const;
174 // Shows the hardlock or connecting state as initial UI before cryptohome
175 // keys checking and state update from the app.
176 void ShowInitialUserState();
178 // Updates the user pod on the signin/lock screen for the user associated with
179 // the service to reflect the provided screenlock state.
180 bool UpdateScreenlockState(proximity_auth::ScreenlockState state
);
182 // Returns the screenlock state if it is available. Otherwise STATE_INACTIVE
184 proximity_auth::ScreenlockState
GetScreenlockState();
186 // Starts an auth attempt for the user associated with the service. The
187 // attempt type (unlock vs. signin) will depend on the service type.
188 void AttemptAuth(const std::string
& user_id
);
190 // Similar to above but a callback is invoked after the auth attempt is
191 // finalized instead of default unlock/sign-in.
192 typedef EasyUnlockAuthAttempt::FinalizedCallback AttemptAuthCallback
;
193 void AttemptAuth(const std::string
& user_id
,
194 const AttemptAuthCallback
& callback
);
196 // Finalizes the previously started auth attempt for easy unlock. If called on
197 // signin profile service, it will cancel the current auth attempt if one
199 void FinalizeUnlock(bool success
);
201 // Finalizes previously started auth attempt for easy signin. If called on
202 // regular profile service, it will cancel the current auth attempt if one
204 void FinalizeSignin(const std::string
& secret
);
206 // Handles Easy Unlock auth failure for the user.
207 void HandleAuthFailure(const std::string
& user_id
);
209 // Checks the consistency between pairing data and cryptohome keys. Set
210 // hardlock state if the two do not match.
211 void CheckCryptohomeKeysAndMaybeHardlock();
213 // Marks the Easy Unlock screen lock state as the one associated with the
214 // trial run initiated by Easy Unlock app.
217 // Records that the user clicked on the lock icon during the trial run
218 // initiated by the Easy Unlock app.
219 void RecordClickOnLockIcon();
221 void AddObserver(EasyUnlockServiceObserver
* observer
);
222 void RemoveObserver(EasyUnlockServiceObserver
* observer
);
224 // ProximityAuthUIDelegate:
225 PrefService
* GetPrefService() override
;
226 scoped_ptr
<proximity_auth::SecureMessageDelegate
>
227 CreateSecureMessageDelegate() override
;
228 scoped_ptr
<proximity_auth::CryptAuthClientFactory
>
229 CreateCryptAuthClientFactory() override
;
230 cryptauth::DeviceClassifier
GetDeviceClassifier() override
;
231 std::string
GetAccountId() override
;
232 gcm::GCMDriver
* GetGCMDriver() override
;
234 ChromeProximityAuthClient
* proximity_auth_client() {
235 return &proximity_auth_client_
;
239 explicit EasyUnlockService(Profile
* profile
);
240 ~EasyUnlockService() override
;
242 // Does a service type specific initialization.
243 virtual void InitializeInternal() = 0;
245 // Does a service type specific shutdown. Called from |Shutdown|.
246 virtual void ShutdownInternal() = 0;
248 // Service type specific tests for whether the service is allowed. Returns
249 // false if service is not allowed. If true is returned, the service may still
250 // not be allowed if common tests fail (e.g. if Bluetooth is not available).
251 virtual bool IsAllowedInternal() const = 0;
253 // Called while processing a user gesture to unlock the screen using Easy
254 // Unlock, just before the screen is unlocked.
255 virtual void OnWillFinalizeUnlock(bool success
) = 0;
257 // Called when the local device resumes after a suspend.
258 virtual void OnSuspendDone() = 0;
260 // KeyedService override:
261 void Shutdown() override
;
263 // Exposes the profile to which the service is attached to subclasses.
264 const Profile
* profile() const { return profile_
; }
265 Profile
* profile() { return profile_
; }
267 // Opens an Easy Unlock Setup app window.
270 // Reloads the Easy unlock component app if it's loaded and resets the lock
272 void ReloadAppAndLockScreen();
274 // Checks whether Easy unlock should be running and updates app state.
275 void UpdateAppState();
277 // Disables easy unlock app without affecting lock screen state.
278 // Used primarily by signin service when user logged in state changes to
279 // logged in but before screen gets unlocked. At this point service shutdown
280 // is imminent and the app can be safely unloaded, but, for esthetic reasons,
281 // the lock screen UI should remain unchanged until the screen unlocks.
282 void DisableAppWithoutResettingScreenlockState();
284 // Notifies the easy unlock app that the user state has been updated.
285 void NotifyUserUpdated();
287 // Notifies observers that the turn off flow status changed.
288 void NotifyTurnOffOperationStatusChanged();
290 // Resets the screenlock state set by this service.
291 void ResetScreenlockState();
293 // Updates |screenlock_state_handler_|'s hardlocked state.
294 void SetScreenlockHardlockedState(
295 EasyUnlockScreenlockStateHandler::HardlockState state
);
297 const EasyUnlockScreenlockStateHandler
* screenlock_state_handler() const {
298 return screenlock_state_handler_
.get();
301 // Saves hardlock state for the given user. Update UI if the currently
302 // associated user is the same.
303 void SetHardlockStateForUser(
304 const std::string
& user_id
,
305 EasyUnlockScreenlockStateHandler::HardlockState state
);
307 // Returns the authentication event for a recent password sign-in or unlock,
308 // according to the current state of the service.
309 EasyUnlockAuthEvent
GetPasswordAuthEvent() const;
312 // A class to detect whether a bluetooth adapter is present.
313 class BluetoothDetector
;
315 // Initializes the service after EasyUnlockAppManager is ready.
316 void InitializeOnAppManagerReady();
318 // Gets |screenlock_state_handler_|. Returns NULL if Easy Unlock is not
319 // allowed. Otherwise, if |screenlock_state_handler_| is not set, an instance
320 // is created. Do not cache the returned value, as it may go away if Easy
321 // Unlock gets disabled.
322 EasyUnlockScreenlockStateHandler
* GetScreenlockStateHandler();
324 // Callback when Bluetooth adapter present state changes.
325 void OnBluetoothAdapterPresentChanged();
327 #if defined(OS_CHROMEOS)
328 // Callback for get key operation from CheckCryptohomeKeysAndMaybeHardlock.
329 void OnCryptohomeKeysFetchedForChecking(
330 const std::string
& user_id
,
331 const std::set
<std::string
> paired_devices
,
333 const chromeos::EasyUnlockDeviceKeyDataList
& key_data_list
);
336 // Updates the service to state for handling system suspend.
337 void PrepareForSuspend();
339 void EnsureTpmKeyPresentIfNeeded();
341 Profile
* const profile_
;
343 ChromeProximityAuthClient proximity_auth_client_
;
345 scoped_ptr
<EasyUnlockAppManager
> app_manager_
;
347 // Created lazily in |GetScreenlockStateHandler|.
348 scoped_ptr
<EasyUnlockScreenlockStateHandler
> screenlock_state_handler_
;
350 // The handler for the current auth attempt. Set iff an auth attempt is in
352 scoped_ptr
<EasyUnlockAuthAttempt
> auth_attempt_
;
354 scoped_ptr
<BluetoothDetector
> bluetooth_detector_
;
356 // The proximity auth over Bluetooth Low Energy system. This is main entry
357 // point to bootstap Smart Lock to discover phones over Bluetooth Low
359 scoped_ptr
<proximity_auth::ProximityAuthBleSystem
> proximity_auth_ble_system_
;
361 #if defined(OS_CHROMEOS)
362 // Monitors suspend and wake state of ChromeOS.
364 scoped_ptr
<PowerMonitor
> power_monitor_
;
367 // Whether the service has been shut down.
370 bool tpm_key_checked_
;
372 base::ObserverList
<EasyUnlockServiceObserver
> observers_
;
374 base::WeakPtrFactory
<EasyUnlockService
> weak_ptr_factory_
;
376 DISALLOW_COPY_AND_ASSIGN(EasyUnlockService
);
379 #endif // CHROME_BROWSER_SIGNIN_EASY_UNLOCK_SERVICE_H_