Home | History | Annotate | Download | only in dbus
      1 // Copyright (c) 2012 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 #include "chromeos/dbus/session_manager_client.h"
      6 
      7 #include <map>
      8 
      9 #include "base/bind.h"
     10 #include "base/callback.h"
     11 #include "base/file_util.h"
     12 #include "base/files/file_path.h"
     13 #include "base/location.h"
     14 #include "base/path_service.h"
     15 #include "base/strings/string_util.h"
     16 #include "base/threading/worker_pool.h"
     17 #include "chromeos/chromeos_paths.h"
     18 #include "chromeos/dbus/blocking_method_caller.h"
     19 #include "chromeos/dbus/cryptohome_client.h"
     20 #include "dbus/bus.h"
     21 #include "dbus/message.h"
     22 #include "dbus/object_path.h"
     23 #include "dbus/object_proxy.h"
     24 #include "third_party/cros_system_api/dbus/service_constants.h"
     25 
     26 namespace chromeos {
     27 
     28 // The SessionManagerClient implementation used in production.
     29 class SessionManagerClientImpl : public SessionManagerClient {
     30  public:
     31   explicit SessionManagerClientImpl(dbus::Bus* bus)
     32       : session_manager_proxy_(bus->GetObjectProxy(
     33             login_manager::kSessionManagerServiceName,
     34             dbus::ObjectPath(login_manager::kSessionManagerServicePath))),
     35         blocking_method_caller_(bus, session_manager_proxy_),
     36         weak_ptr_factory_(this) {
     37     // Signals emitted on Chromium's interface.  Many of these ought to be
     38     // method calls instead.
     39     session_manager_proxy_->ConnectToSignal(
     40         chromium::kChromiumInterface,
     41         chromium::kOwnerKeySetSignal,
     42         base::Bind(&SessionManagerClientImpl::OwnerKeySetReceived,
     43                    weak_ptr_factory_.GetWeakPtr()),
     44         base::Bind(&SessionManagerClientImpl::SignalConnected,
     45                    weak_ptr_factory_.GetWeakPtr()));
     46     session_manager_proxy_->ConnectToSignal(
     47         chromium::kChromiumInterface,
     48         chromium::kPropertyChangeCompleteSignal,
     49         base::Bind(&SessionManagerClientImpl::PropertyChangeCompleteReceived,
     50                    weak_ptr_factory_.GetWeakPtr()),
     51         base::Bind(&SessionManagerClientImpl::SignalConnected,
     52                    weak_ptr_factory_.GetWeakPtr()));
     53     session_manager_proxy_->ConnectToSignal(
     54         chromium::kChromiumInterface,
     55         chromium::kLockScreenSignal,
     56         base::Bind(&SessionManagerClientImpl::ScreenLockReceived,
     57                    weak_ptr_factory_.GetWeakPtr()),
     58         base::Bind(&SessionManagerClientImpl::SignalConnected,
     59                    weak_ptr_factory_.GetWeakPtr()));
     60     session_manager_proxy_->ConnectToSignal(
     61         chromium::kChromiumInterface,
     62         chromium::kUnlockScreenSignal,
     63         base::Bind(&SessionManagerClientImpl::ScreenUnlockReceived,
     64                    weak_ptr_factory_.GetWeakPtr()),
     65         base::Bind(&SessionManagerClientImpl::SignalConnected,
     66                    weak_ptr_factory_.GetWeakPtr()));
     67     session_manager_proxy_->ConnectToSignal(
     68         chromium::kChromiumInterface,
     69         chromium::kLivenessRequestedSignal,
     70         base::Bind(&SessionManagerClientImpl::LivenessRequestedReceived,
     71                    weak_ptr_factory_.GetWeakPtr()),
     72         base::Bind(&SessionManagerClientImpl::SignalConnected,
     73                    weak_ptr_factory_.GetWeakPtr()));
     74 
     75     // Signals emitted on the session manager's interface.
     76     session_manager_proxy_->ConnectToSignal(
     77         login_manager::kSessionManagerInterface,
     78         login_manager::kScreenIsLockedSignal,
     79         base::Bind(&SessionManagerClientImpl::ScreenIsLockedReceived,
     80                    weak_ptr_factory_.GetWeakPtr()),
     81         base::Bind(&SessionManagerClientImpl::SignalConnected,
     82                    weak_ptr_factory_.GetWeakPtr()));
     83     session_manager_proxy_->ConnectToSignal(
     84         login_manager::kSessionManagerInterface,
     85         login_manager::kScreenIsUnlockedSignal,
     86         base::Bind(&SessionManagerClientImpl::ScreenIsUnlockedReceived,
     87                    weak_ptr_factory_.GetWeakPtr()),
     88         base::Bind(&SessionManagerClientImpl::SignalConnected,
     89                    weak_ptr_factory_.GetWeakPtr()));
     90   }
     91 
     92   virtual ~SessionManagerClientImpl() {
     93   }
     94 
     95   // SessionManagerClient overrides:
     96   virtual void AddObserver(Observer* observer) OVERRIDE {
     97     observers_.AddObserver(observer);
     98   }
     99 
    100   virtual void RemoveObserver(Observer* observer) OVERRIDE {
    101     observers_.RemoveObserver(observer);
    102   }
    103 
    104   virtual bool HasObserver(Observer* observer) OVERRIDE {
    105     return observers_.HasObserver(observer);
    106   }
    107 
    108   virtual void EmitLoginPromptReady() OVERRIDE {
    109     SimpleMethodCallToSessionManager(
    110         login_manager::kSessionManagerEmitLoginPromptReady);
    111   }
    112 
    113   virtual void EmitLoginPromptVisible() OVERRIDE {
    114     SimpleMethodCallToSessionManager(
    115         login_manager::kSessionManagerEmitLoginPromptVisible);
    116   }
    117 
    118   virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {
    119     dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
    120                                  login_manager::kSessionManagerRestartJob);
    121     dbus::MessageWriter writer(&method_call);
    122     writer.AppendInt32(pid);
    123     writer.AppendString(command_line);
    124     session_manager_proxy_->CallMethod(
    125         &method_call,
    126         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    127         base::Bind(&SessionManagerClientImpl::OnRestartJob,
    128                    weak_ptr_factory_.GetWeakPtr()));
    129   }
    130 
    131   virtual void RestartEntd() OVERRIDE {
    132     SimpleMethodCallToSessionManager(login_manager::kSessionManagerRestartEntd);
    133   }
    134 
    135   virtual void StartSession(const std::string& user_email) OVERRIDE {
    136     dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
    137                                  login_manager::kSessionManagerStartSession);
    138     dbus::MessageWriter writer(&method_call);
    139     writer.AppendString(user_email);
    140     writer.AppendString("");  // Unique ID is deprecated
    141     session_manager_proxy_->CallMethod(
    142         &method_call,
    143         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    144         base::Bind(&SessionManagerClientImpl::OnStartSession,
    145                    weak_ptr_factory_.GetWeakPtr()));
    146   }
    147 
    148   virtual void StopSession() OVERRIDE {
    149     dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
    150                                  login_manager::kSessionManagerStopSession);
    151     dbus::MessageWriter writer(&method_call);
    152     writer.AppendString("");  // Unique ID is deprecated
    153     session_manager_proxy_->CallMethod(
    154         &method_call,
    155         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    156         base::Bind(&SessionManagerClientImpl::OnStopSession,
    157                    weak_ptr_factory_.GetWeakPtr()));
    158   }
    159 
    160   virtual void StartDeviceWipe() OVERRIDE {
    161     dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
    162                                  login_manager::kSessionManagerStartDeviceWipe);
    163     session_manager_proxy_->CallMethod(
    164         &method_call,
    165         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    166         base::Bind(&SessionManagerClientImpl::OnDeviceWipe,
    167                    weak_ptr_factory_.GetWeakPtr()));
    168   }
    169 
    170   virtual void RequestLockScreen() OVERRIDE {
    171     SimpleMethodCallToSessionManager(login_manager::kSessionManagerLockScreen);
    172   }
    173 
    174   virtual void NotifyLockScreenShown() OVERRIDE {
    175     SimpleMethodCallToSessionManager(
    176         login_manager::kSessionManagerHandleLockScreenShown);
    177   }
    178 
    179   virtual void RequestUnlockScreen() OVERRIDE {
    180     SimpleMethodCallToSessionManager(
    181         login_manager::kSessionManagerUnlockScreen);
    182   }
    183 
    184   virtual void NotifyLockScreenDismissed() OVERRIDE {
    185     SimpleMethodCallToSessionManager(
    186         login_manager::kSessionManagerHandleLockScreenDismissed);
    187   }
    188 
    189   virtual void RetrieveActiveSessions(
    190       const ActiveSessionsCallback& callback) OVERRIDE {
    191     dbus::MethodCall method_call(
    192         login_manager::kSessionManagerInterface,
    193         login_manager::kSessionManagerRetrieveActiveSessions);
    194 
    195     session_manager_proxy_->CallMethod(
    196         &method_call,
    197         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    198         base::Bind(&SessionManagerClientImpl::OnRetrieveActiveSessions,
    199                    weak_ptr_factory_.GetWeakPtr(),
    200                    login_manager::kSessionManagerRetrieveActiveSessions,
    201                    callback));
    202   }
    203 
    204   virtual void RetrieveDevicePolicy(
    205       const RetrievePolicyCallback& callback) OVERRIDE {
    206     dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
    207                                  login_manager::kSessionManagerRetrievePolicy);
    208     session_manager_proxy_->CallMethod(
    209         &method_call,
    210         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    211         base::Bind(&SessionManagerClientImpl::OnRetrievePolicy,
    212                    weak_ptr_factory_.GetWeakPtr(),
    213                    login_manager::kSessionManagerRetrievePolicy,
    214                    callback));
    215   }
    216 
    217   virtual void RetrievePolicyForUser(
    218       const std::string& username,
    219       const RetrievePolicyCallback& callback) OVERRIDE {
    220     CallRetrievePolicyByUsername(
    221         login_manager::kSessionManagerRetrievePolicyForUser,
    222         username,
    223         callback);
    224   }
    225 
    226   virtual std::string BlockingRetrievePolicyForUser(
    227       const std::string& username) OVERRIDE {
    228     dbus::MethodCall method_call(
    229         login_manager::kSessionManagerInterface,
    230         login_manager::kSessionManagerRetrievePolicyForUser);
    231     dbus::MessageWriter writer(&method_call);
    232     writer.AppendString(username);
    233     scoped_ptr<dbus::Response> response =
    234         blocking_method_caller_.CallMethodAndBlock(&method_call);
    235     std::string policy;
    236     ExtractString(login_manager::kSessionManagerRetrievePolicyForUser,
    237                   response.get(),
    238                   &policy);
    239     return policy;
    240   }
    241 
    242   virtual void RetrieveDeviceLocalAccountPolicy(
    243       const std::string& account_name,
    244       const RetrievePolicyCallback& callback) OVERRIDE {
    245     CallRetrievePolicyByUsername(
    246         login_manager::kSessionManagerRetrieveDeviceLocalAccountPolicy,
    247         account_name,
    248         callback);
    249   }
    250 
    251   virtual void StoreDevicePolicy(const std::string& policy_blob,
    252                                  const StorePolicyCallback& callback) OVERRIDE {
    253     dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
    254                                  login_manager::kSessionManagerStorePolicy);
    255     dbus::MessageWriter writer(&method_call);
    256     // static_cast does not work due to signedness.
    257     writer.AppendArrayOfBytes(
    258         reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size());
    259     session_manager_proxy_->CallMethod(
    260         &method_call,
    261         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    262         base::Bind(&SessionManagerClientImpl::OnStorePolicy,
    263                    weak_ptr_factory_.GetWeakPtr(),
    264                    login_manager::kSessionManagerStorePolicy,
    265                    callback));
    266   }
    267 
    268   virtual void StorePolicyForUser(
    269       const std::string& username,
    270       const std::string& policy_blob,
    271       const std::string& ignored_policy_key,
    272       const StorePolicyCallback& callback) OVERRIDE {
    273     CallStorePolicyByUsername(login_manager::kSessionManagerStorePolicyForUser,
    274                               username,
    275                               policy_blob,
    276                               callback);
    277   }
    278 
    279   virtual void StoreDeviceLocalAccountPolicy(
    280       const std::string& account_name,
    281       const std::string& policy_blob,
    282       const StorePolicyCallback& callback) OVERRIDE {
    283     CallStorePolicyByUsername(
    284         login_manager::kSessionManagerStoreDeviceLocalAccountPolicy,
    285         account_name,
    286         policy_blob,
    287         callback);
    288   }
    289 
    290   virtual void SetFlagsForUser(const std::string& username,
    291                                const std::vector<std::string>& flags) OVERRIDE {
    292     dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
    293                                  login_manager::kSessionManagerSetFlagsForUser);
    294     dbus::MessageWriter writer(&method_call);
    295     writer.AppendString(username);
    296     writer.AppendArrayOfStrings(flags);
    297     session_manager_proxy_->CallMethod(
    298         &method_call,
    299         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    300         dbus::ObjectProxy::EmptyResponseCallback());
    301   }
    302 
    303  private:
    304   // Makes a method call to the session manager with no arguments and no
    305   // response.
    306   void SimpleMethodCallToSessionManager(const std::string& method_name) {
    307     dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
    308                                  method_name);
    309     session_manager_proxy_->CallMethod(
    310         &method_call,
    311         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    312         dbus::ObjectProxy::EmptyResponseCallback());
    313   }
    314 
    315   // Helper for RetrieveDeviceLocalAccountPolicy and RetrievePolicyForUser.
    316   void CallRetrievePolicyByUsername(const std::string& method_name,
    317                                     const std::string& username,
    318                                     const RetrievePolicyCallback& callback) {
    319     dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
    320                                  method_name);
    321     dbus::MessageWriter writer(&method_call);
    322     writer.AppendString(username);
    323     session_manager_proxy_->CallMethod(
    324         &method_call,
    325         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    326         base::Bind(
    327             &SessionManagerClientImpl::OnRetrievePolicy,
    328             weak_ptr_factory_.GetWeakPtr(),
    329             method_name,
    330             callback));
    331   }
    332 
    333   void CallStorePolicyByUsername(const std::string& method_name,
    334                                  const std::string& username,
    335                                  const std::string& policy_blob,
    336                                  const StorePolicyCallback& callback) {
    337     dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
    338                                  method_name);
    339     dbus::MessageWriter writer(&method_call);
    340     writer.AppendString(username);
    341     // static_cast does not work due to signedness.
    342     writer.AppendArrayOfBytes(
    343         reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size());
    344     session_manager_proxy_->CallMethod(
    345         &method_call,
    346         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    347         base::Bind(
    348             &SessionManagerClientImpl::OnStorePolicy,
    349             weak_ptr_factory_.GetWeakPtr(),
    350             method_name,
    351             callback));
    352   }
    353 
    354   // Called when kSessionManagerRestartJob method is complete.
    355   void OnRestartJob(dbus::Response* response) {
    356     LOG_IF(ERROR, !response)
    357         << "Failed to call "
    358         << login_manager::kSessionManagerRestartJob;
    359   }
    360 
    361   // Called when kSessionManagerStartSession method is complete.
    362   void OnStartSession(dbus::Response* response) {
    363     LOG_IF(ERROR, !response)
    364         << "Failed to call "
    365         << login_manager::kSessionManagerStartSession;
    366   }
    367 
    368   // Called when kSessionManagerStopSession method is complete.
    369   void OnStopSession(dbus::Response* response) {
    370     LOG_IF(ERROR, !response)
    371         << "Failed to call "
    372         << login_manager::kSessionManagerStopSession;
    373   }
    374 
    375   // Called when kSessionManagerStopSession method is complete.
    376   void OnDeviceWipe(dbus::Response* response) {
    377     LOG_IF(ERROR, !response)
    378         << "Failed to call "
    379         << login_manager::kSessionManagerStartDeviceWipe;
    380   }
    381 
    382   // Called when kSessionManagerRetrieveActiveSessions method is complete.
    383   void OnRetrieveActiveSessions(const std::string& method_name,
    384                                 const ActiveSessionsCallback& callback,
    385                                 dbus::Response* response) {
    386     ActiveSessionsMap sessions;
    387     bool success = false;
    388     if (!response) {
    389       LOG(ERROR) << "Failed to call " << method_name;
    390       callback.Run(sessions, success);
    391       return;
    392     }
    393 
    394     dbus::MessageReader reader(response);
    395     dbus::MessageReader array_reader(NULL);
    396 
    397     if (!reader.PopArray(&array_reader)) {
    398       LOG(ERROR) << method_name << " response is incorrect: "
    399                  << response->ToString();
    400     } else {
    401       while (array_reader.HasMoreData()) {
    402         dbus::MessageReader dict_entry_reader(NULL);
    403         std::string key;
    404         std::string value;
    405         if (!array_reader.PopDictEntry(&dict_entry_reader) ||
    406             !dict_entry_reader.PopString(&key) ||
    407             !dict_entry_reader.PopString(&value)) {
    408           LOG(ERROR) << method_name << " response is incorrect: "
    409                      << response->ToString();
    410         } else {
    411           sessions[key] = value;
    412         }
    413       }
    414       success = true;
    415     }
    416     callback.Run(sessions, success);
    417   }
    418 
    419   void ExtractString(const std::string& method_name,
    420                      dbus::Response* response,
    421                      std::string* extracted) {
    422     if (!response) {
    423       LOG(ERROR) << "Failed to call " << method_name;
    424       return;
    425     }
    426     dbus::MessageReader reader(response);
    427     uint8* values = NULL;
    428     size_t length = 0;
    429     if (!reader.PopArrayOfBytes(&values, &length)) {
    430       LOG(ERROR) << "Invalid response: " << response->ToString();
    431       return;
    432     }
    433     // static_cast does not work due to signedness.
    434     extracted->assign(reinterpret_cast<char*>(values), length);
    435   }
    436 
    437   // Called when kSessionManagerRetrievePolicy or
    438   // kSessionManagerRetrievePolicyForUser method is complete.
    439   void OnRetrievePolicy(const std::string& method_name,
    440                         const RetrievePolicyCallback& callback,
    441                         dbus::Response* response) {
    442     std::string serialized_proto;
    443     ExtractString(method_name, response, &serialized_proto);
    444     callback.Run(serialized_proto);
    445   }
    446 
    447   // Called when kSessionManagerStorePolicy or kSessionManagerStorePolicyForUser
    448   // method is complete.
    449   void OnStorePolicy(const std::string& method_name,
    450                      const StorePolicyCallback& callback,
    451                      dbus::Response* response) {
    452     bool success = false;
    453     if (!response) {
    454       LOG(ERROR) << "Failed to call " << method_name;
    455     } else {
    456       dbus::MessageReader reader(response);
    457       if (!reader.PopBool(&success))
    458         LOG(ERROR) << "Invalid response: " << response->ToString();
    459     }
    460     callback.Run(success);
    461   }
    462 
    463   // Called when the owner key set signal is received.
    464   void OwnerKeySetReceived(dbus::Signal* signal) {
    465     dbus::MessageReader reader(signal);
    466     std::string result_string;
    467     if (!reader.PopString(&result_string)) {
    468       LOG(ERROR) << "Invalid signal: " << signal->ToString();
    469       return;
    470     }
    471     const bool success = StartsWithASCII(result_string, "success", false);
    472     FOR_EACH_OBSERVER(Observer, observers_, OwnerKeySet(success));
    473   }
    474 
    475   // Called when the property change complete signal is received.
    476   void PropertyChangeCompleteReceived(dbus::Signal* signal) {
    477     dbus::MessageReader reader(signal);
    478     std::string result_string;
    479     if (!reader.PopString(&result_string)) {
    480       LOG(ERROR) << "Invalid signal: " << signal->ToString();
    481       return;
    482     }
    483     const bool success = StartsWithASCII(result_string, "success", false);
    484     FOR_EACH_OBSERVER(Observer, observers_, PropertyChangeComplete(success));
    485   }
    486 
    487   void ScreenLockReceived(dbus::Signal* signal) {
    488     FOR_EACH_OBSERVER(Observer, observers_, LockScreen());
    489   }
    490 
    491   void ScreenUnlockReceived(dbus::Signal* signal) {
    492     FOR_EACH_OBSERVER(Observer, observers_, UnlockScreen());
    493   }
    494 
    495   void LivenessRequestedReceived(dbus::Signal* signal) {
    496     SimpleMethodCallToSessionManager(
    497         login_manager::kSessionManagerHandleLivenessConfirmed);
    498   }
    499 
    500   void ScreenIsLockedReceived(dbus::Signal* signal) {
    501     FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked());
    502   }
    503 
    504   void ScreenIsUnlockedReceived(dbus::Signal* signal) {
    505     FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked());
    506   }
    507 
    508   // Called when the object is connected to the signal.
    509   void SignalConnected(const std::string& interface_name,
    510                        const std::string& signal_name,
    511                        bool success) {
    512     LOG_IF(ERROR, !success) << "Failed to connect to " << signal_name;
    513   }
    514 
    515   dbus::ObjectProxy* session_manager_proxy_;
    516   BlockingMethodCaller blocking_method_caller_;
    517   ObserverList<Observer> observers_;
    518 
    519   // Note: This should remain the last member so it'll be destroyed and
    520   // invalidate its weak pointers before any other members are destroyed.
    521   base::WeakPtrFactory<SessionManagerClientImpl> weak_ptr_factory_;
    522 
    523   DISALLOW_COPY_AND_ASSIGN(SessionManagerClientImpl);
    524 };
    525 
    526 // The SessionManagerClient implementation used on Linux desktop,
    527 // which does nothing.
    528 class SessionManagerClientStubImpl : public SessionManagerClient {
    529  public:
    530   SessionManagerClientStubImpl() {
    531     // Make sure that there are no keys left over from a previous browser run.
    532     base::FilePath user_policy_key_dir;
    533     if (PathService::Get(chromeos::DIR_USER_POLICY_KEYS,
    534                          &user_policy_key_dir)) {
    535       base::WorkerPool::PostTask(
    536           FROM_HERE,
    537           base::Bind(base::IgnoreResult(&base::DeleteFile),
    538                      user_policy_key_dir, true),
    539           false);
    540     }
    541   }
    542   virtual ~SessionManagerClientStubImpl() {}
    543 
    544   // SessionManagerClient overrides.
    545   virtual void AddObserver(Observer* observer) OVERRIDE {
    546     observers_.AddObserver(observer);
    547   }
    548   virtual void RemoveObserver(Observer* observer) OVERRIDE {
    549     observers_.RemoveObserver(observer);
    550   }
    551   virtual bool HasObserver(Observer* observer) OVERRIDE {
    552     return observers_.HasObserver(observer);
    553   }
    554   virtual void EmitLoginPromptReady() OVERRIDE {}
    555   virtual void EmitLoginPromptVisible() OVERRIDE {}
    556   virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {}
    557   virtual void RestartEntd() OVERRIDE {}
    558   virtual void StartSession(const std::string& user_email) OVERRIDE {}
    559   virtual void StopSession() OVERRIDE {}
    560   virtual void StartDeviceWipe() OVERRIDE {}
    561   virtual void RequestLockScreen() OVERRIDE {
    562     FOR_EACH_OBSERVER(Observer, observers_, LockScreen());
    563   }
    564   virtual void NotifyLockScreenShown() OVERRIDE {
    565     FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked());
    566   }
    567   virtual void RequestUnlockScreen() OVERRIDE {
    568     FOR_EACH_OBSERVER(Observer, observers_, UnlockScreen());
    569   }
    570   virtual void NotifyLockScreenDismissed() OVERRIDE {
    571     FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked());
    572   }
    573   virtual void RetrieveActiveSessions(
    574       const ActiveSessionsCallback& callback) OVERRIDE {}
    575   virtual void RetrieveDevicePolicy(
    576       const RetrievePolicyCallback& callback) OVERRIDE {
    577     callback.Run(device_policy_);
    578   }
    579   virtual void RetrievePolicyForUser(
    580       const std::string& username,
    581       const RetrievePolicyCallback& callback) OVERRIDE {
    582     callback.Run(user_policies_[username]);
    583   }
    584   virtual std::string BlockingRetrievePolicyForUser(
    585       const std::string& username) OVERRIDE {
    586     return user_policies_[username];
    587   }
    588   virtual void RetrieveDeviceLocalAccountPolicy(
    589       const std::string& account_name,
    590       const RetrievePolicyCallback& callback) OVERRIDE {
    591     callback.Run(user_policies_[account_name]);
    592   }
    593   virtual void StoreDevicePolicy(const std::string& policy_blob,
    594                                  const StorePolicyCallback& callback) OVERRIDE {
    595     device_policy_ = policy_blob;
    596     callback.Run(true);
    597   }
    598   virtual void StorePolicyForUser(
    599       const std::string& username,
    600       const std::string& policy_blob,
    601       const std::string& policy_key,
    602       const StorePolicyCallback& callback) OVERRIDE {
    603     if (policy_key.empty()) {
    604       user_policies_[username] = policy_blob;
    605       callback.Run(true);
    606       return;
    607     }
    608     // The session manager writes the user policy key to a well-known
    609     // location. Do the same with the stub impl, so that user policy works and
    610     // can be tested on desktop builds.
    611     // TODO(joaodasilva): parse the PolicyFetchResponse in |policy_blob| to get
    612     // the policy key directly, after moving the policy protobufs to a top-level
    613     // directory. The |policy_key| argument to this method can then be removed.
    614     // http://crbug.com/240269
    615     base::FilePath key_path;
    616     if (!PathService::Get(chromeos::DIR_USER_POLICY_KEYS, &key_path)) {
    617       callback.Run(false);
    618       return;
    619     }
    620     const std::string sanitized =
    621         CryptohomeClient::GetStubSanitizedUsername(username);
    622     key_path = key_path.AppendASCII(sanitized).AppendASCII("policy.pub");
    623     // Assume that the key write is successful.
    624     user_policies_[username] = policy_blob;
    625     base::WorkerPool::PostTaskAndReply(
    626         FROM_HERE,
    627         base::Bind(&SessionManagerClientStubImpl::StoreFileInBackground,
    628                    key_path, policy_key),
    629         base::Bind(callback, true),
    630         false);
    631   }
    632   virtual void StoreDeviceLocalAccountPolicy(
    633       const std::string& account_name,
    634       const std::string& policy_blob,
    635       const StorePolicyCallback& callback) OVERRIDE {
    636     user_policies_[account_name] = policy_blob;
    637     callback.Run(true);
    638   }
    639   virtual void SetFlagsForUser(const std::string& username,
    640                                const std::vector<std::string>& flags) OVERRIDE {
    641   }
    642 
    643   static void StoreFileInBackground(const base::FilePath& path,
    644                                     const std::string& data) {
    645     const int size = static_cast<int>(data.size());
    646     if (!file_util::CreateDirectory(path.DirName()) ||
    647         file_util::WriteFile(path, data.data(), size) != size) {
    648       LOG(WARNING) << "Failed to write policy key to " << path.value();
    649     }
    650   }
    651 
    652  private:
    653   ObserverList<Observer> observers_;
    654   std::string device_policy_;
    655   std::map<std::string, std::string> user_policies_;
    656 
    657   DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl);
    658 };
    659 
    660 SessionManagerClient::SessionManagerClient() {
    661 }
    662 
    663 SessionManagerClient::~SessionManagerClient() {
    664 }
    665 
    666 SessionManagerClient* SessionManagerClient::Create(
    667     DBusClientImplementationType type,
    668     dbus::Bus* bus) {
    669   if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
    670     return new SessionManagerClientImpl(bus);
    671   DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
    672   return new SessionManagerClientStubImpl();
    673 }
    674 
    675 }  // namespace chromeos
    676