Home | History | Annotate | Download | only in signin
      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