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