session_manager_client.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
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/cryptohome_client.h"
19#include "dbus/bus.h"
20#include "dbus/message.h"
21#include "dbus/object_path.h"
22#include "dbus/object_proxy.h"
23#include "third_party/cros_system_api/dbus/service_constants.h"
24
25namespace chromeos {
26
27// The SessionManagerClient implementation used in production.
28class SessionManagerClientImpl : public SessionManagerClient {
29 public:
30  explicit SessionManagerClientImpl(dbus::Bus* bus)
31      : session_manager_proxy_(NULL),
32        weak_ptr_factory_(this) {
33    session_manager_proxy_ = bus->GetObjectProxy(
34        login_manager::kSessionManagerServiceName,
35        dbus::ObjectPath(login_manager::kSessionManagerServicePath));
36
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 void RetrieveDeviceLocalAccountPolicy(
227      const std::string& account_name,
228      const RetrievePolicyCallback& callback) OVERRIDE {
229    CallRetrievePolicyByUsername(
230        login_manager::kSessionManagerRetrieveDeviceLocalAccountPolicy,
231        account_name,
232        callback);
233  }
234
235  virtual void StoreDevicePolicy(const std::string& policy_blob,
236                                 const StorePolicyCallback& callback) OVERRIDE {
237    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
238                                 login_manager::kSessionManagerStorePolicy);
239    dbus::MessageWriter writer(&method_call);
240    // static_cast does not work due to signedness.
241    writer.AppendArrayOfBytes(
242        reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size());
243    session_manager_proxy_->CallMethod(
244        &method_call,
245        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
246        base::Bind(&SessionManagerClientImpl::OnStorePolicy,
247                   weak_ptr_factory_.GetWeakPtr(),
248                   login_manager::kSessionManagerStorePolicy,
249                   callback));
250  }
251
252  virtual void StorePolicyForUser(
253      const std::string& username,
254      const std::string& policy_blob,
255      const std::string& ignored_policy_key,
256      const StorePolicyCallback& callback) OVERRIDE {
257    CallStorePolicyByUsername(login_manager::kSessionManagerStorePolicyForUser,
258                              username,
259                              policy_blob,
260                              callback);
261  }
262
263  virtual void StoreDeviceLocalAccountPolicy(
264      const std::string& account_name,
265      const std::string& policy_blob,
266      const StorePolicyCallback& callback) OVERRIDE {
267    CallStorePolicyByUsername(
268        login_manager::kSessionManagerStoreDeviceLocalAccountPolicy,
269        account_name,
270        policy_blob,
271        callback);
272  }
273
274  virtual void SetFlagsForUser(const std::string& username,
275                               const std::vector<std::string>& flags) OVERRIDE {
276    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
277                                 login_manager::kSessionManagerSetFlagsForUser);
278    dbus::MessageWriter writer(&method_call);
279    writer.AppendString(username);
280    writer.AppendArrayOfStrings(flags);
281    session_manager_proxy_->CallMethod(
282        &method_call,
283        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
284        dbus::ObjectProxy::EmptyResponseCallback());
285  }
286
287 private:
288  // Makes a method call to the session manager with no arguments and no
289  // response.
290  void SimpleMethodCallToSessionManager(const std::string& method_name) {
291    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
292                                 method_name);
293    session_manager_proxy_->CallMethod(
294        &method_call,
295        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
296        dbus::ObjectProxy::EmptyResponseCallback());
297  }
298
299  // Helper for RetrieveDeviceLocalAccountPolicy and RetrievePolicyForUser.
300  void CallRetrievePolicyByUsername(const std::string& method_name,
301                                    const std::string& username,
302                                    const RetrievePolicyCallback& callback) {
303    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
304                                 method_name);
305    dbus::MessageWriter writer(&method_call);
306    writer.AppendString(username);
307    session_manager_proxy_->CallMethod(
308        &method_call,
309        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
310        base::Bind(
311            &SessionManagerClientImpl::OnRetrievePolicy,
312            weak_ptr_factory_.GetWeakPtr(),
313            method_name,
314            callback));
315  }
316
317  void CallStorePolicyByUsername(const std::string& method_name,
318                                 const std::string& username,
319                                 const std::string& policy_blob,
320                                 const StorePolicyCallback& callback) {
321    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
322                                 method_name);
323    dbus::MessageWriter writer(&method_call);
324    writer.AppendString(username);
325    // static_cast does not work due to signedness.
326    writer.AppendArrayOfBytes(
327        reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size());
328    session_manager_proxy_->CallMethod(
329        &method_call,
330        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
331        base::Bind(
332            &SessionManagerClientImpl::OnStorePolicy,
333            weak_ptr_factory_.GetWeakPtr(),
334            method_name,
335            callback));
336  }
337
338  // Called when kSessionManagerRestartJob method is complete.
339  void OnRestartJob(dbus::Response* response) {
340    LOG_IF(ERROR, !response)
341        << "Failed to call "
342        << login_manager::kSessionManagerRestartJob;
343  }
344
345  // Called when kSessionManagerStartSession method is complete.
346  void OnStartSession(dbus::Response* response) {
347    LOG_IF(ERROR, !response)
348        << "Failed to call "
349        << login_manager::kSessionManagerStartSession;
350  }
351
352  // Called when kSessionManagerStopSession method is complete.
353  void OnStopSession(dbus::Response* response) {
354    LOG_IF(ERROR, !response)
355        << "Failed to call "
356        << login_manager::kSessionManagerStopSession;
357  }
358
359  // Called when kSessionManagerStopSession method is complete.
360  void OnDeviceWipe(dbus::Response* response) {
361    LOG_IF(ERROR, !response)
362        << "Failed to call "
363        << login_manager::kSessionManagerStartDeviceWipe;
364  }
365
366  // Called when kSessionManagerRetrieveActiveSessions method is complete.
367  void OnRetrieveActiveSessions(const std::string& method_name,
368                                const ActiveSessionsCallback& callback,
369                                dbus::Response* response) {
370    ActiveSessionsMap sessions;
371    bool success = false;
372    if (!response) {
373      LOG(ERROR) << "Failed to call " << method_name;
374      callback.Run(sessions, success);
375      return;
376    }
377
378    dbus::MessageReader reader(response);
379    dbus::MessageReader array_reader(NULL);
380
381    if (!reader.PopArray(&array_reader)) {
382      LOG(ERROR) << method_name << " response is incorrect: "
383                 << response->ToString();
384    } else {
385      while (array_reader.HasMoreData()) {
386        dbus::MessageReader dict_entry_reader(NULL);
387        std::string key;
388        std::string value;
389        if (!array_reader.PopDictEntry(&dict_entry_reader) ||
390            !dict_entry_reader.PopString(&key) ||
391            !dict_entry_reader.PopString(&value)) {
392          LOG(ERROR) << method_name << " response is incorrect: "
393                     << response->ToString();
394        } else {
395          sessions[key] = value;
396        }
397      }
398      success = true;
399    }
400    callback.Run(sessions, success);
401  }
402
403  // Called when kSessionManagerRetrievePolicy or
404  // kSessionManagerRetrievePolicyForUser method is complete.
405  void OnRetrievePolicy(const std::string& method_name,
406                        const RetrievePolicyCallback& callback,
407                        dbus::Response* response) {
408    if (!response) {
409      LOG(ERROR) << "Failed to call " << method_name;
410      callback.Run("");
411      return;
412    }
413    dbus::MessageReader reader(response);
414    uint8* values = NULL;
415    size_t length = 0;
416    if (!reader.PopArrayOfBytes(&values, &length)) {
417      LOG(ERROR) << "Invalid response: " << response->ToString();
418      callback.Run("");
419      return;
420    }
421    // static_cast does not work due to signedness.
422    std::string serialized_proto(reinterpret_cast<char*>(values), length);
423    callback.Run(serialized_proto);
424  }
425
426  // Called when kSessionManagerStorePolicy or kSessionManagerStorePolicyForUser
427  // method is complete.
428  void OnStorePolicy(const std::string& method_name,
429                     const StorePolicyCallback& callback,
430                     dbus::Response* response) {
431    bool success = false;
432    if (!response) {
433      LOG(ERROR) << "Failed to call " << method_name;
434    } else {
435      dbus::MessageReader reader(response);
436      if (!reader.PopBool(&success))
437        LOG(ERROR) << "Invalid response: " << response->ToString();
438    }
439    callback.Run(success);
440  }
441
442  // Called when the owner key set signal is received.
443  void OwnerKeySetReceived(dbus::Signal* signal) {
444    dbus::MessageReader reader(signal);
445    std::string result_string;
446    if (!reader.PopString(&result_string)) {
447      LOG(ERROR) << "Invalid signal: " << signal->ToString();
448      return;
449    }
450    const bool success = StartsWithASCII(result_string, "success", false);
451    FOR_EACH_OBSERVER(Observer, observers_, OwnerKeySet(success));
452  }
453
454  // Called when the property change complete signal is received.
455  void PropertyChangeCompleteReceived(dbus::Signal* signal) {
456    dbus::MessageReader reader(signal);
457    std::string result_string;
458    if (!reader.PopString(&result_string)) {
459      LOG(ERROR) << "Invalid signal: " << signal->ToString();
460      return;
461    }
462    const bool success = StartsWithASCII(result_string, "success", false);
463    FOR_EACH_OBSERVER(Observer, observers_, PropertyChangeComplete(success));
464  }
465
466  void ScreenLockReceived(dbus::Signal* signal) {
467    FOR_EACH_OBSERVER(Observer, observers_, LockScreen());
468  }
469
470  void ScreenUnlockReceived(dbus::Signal* signal) {
471    FOR_EACH_OBSERVER(Observer, observers_, UnlockScreen());
472  }
473
474  void LivenessRequestedReceived(dbus::Signal* signal) {
475    SimpleMethodCallToSessionManager(
476        login_manager::kSessionManagerHandleLivenessConfirmed);
477  }
478
479  void ScreenIsLockedReceived(dbus::Signal* signal) {
480    FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked());
481  }
482
483  void ScreenIsUnlockedReceived(dbus::Signal* signal) {
484    FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked());
485  }
486
487  // Called when the object is connected to the signal.
488  void SignalConnected(const std::string& interface_name,
489                       const std::string& signal_name,
490                       bool success) {
491    LOG_IF(ERROR, !success) << "Failed to connect to " << signal_name;
492  }
493
494  dbus::ObjectProxy* session_manager_proxy_;
495  ObserverList<Observer> observers_;
496
497  // Note: This should remain the last member so it'll be destroyed and
498  // invalidate its weak pointers before any other members are destroyed.
499  base::WeakPtrFactory<SessionManagerClientImpl> weak_ptr_factory_;
500
501  DISALLOW_COPY_AND_ASSIGN(SessionManagerClientImpl);
502};
503
504// The SessionManagerClient implementation used on Linux desktop,
505// which does nothing.
506class SessionManagerClientStubImpl : public SessionManagerClient {
507 public:
508  SessionManagerClientStubImpl() {
509    // Make sure that there are no keys left over from a previous browser run.
510    base::FilePath user_policy_key_dir;
511    if (PathService::Get(chromeos::DIR_USER_POLICY_KEYS,
512                         &user_policy_key_dir)) {
513      base::WorkerPool::PostTask(
514          FROM_HERE,
515          base::Bind(base::IgnoreResult(&file_util::Delete),
516                     user_policy_key_dir, true),
517          false);
518    }
519  }
520  virtual ~SessionManagerClientStubImpl() {}
521
522  // SessionManagerClient overrides.
523  virtual void AddObserver(Observer* observer) OVERRIDE {
524    observers_.AddObserver(observer);
525  }
526  virtual void RemoveObserver(Observer* observer) OVERRIDE {
527    observers_.RemoveObserver(observer);
528  }
529  virtual bool HasObserver(Observer* observer) OVERRIDE {
530    return observers_.HasObserver(observer);
531  }
532  virtual void EmitLoginPromptReady() OVERRIDE {}
533  virtual void EmitLoginPromptVisible() OVERRIDE {}
534  virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {}
535  virtual void RestartEntd() OVERRIDE {}
536  virtual void StartSession(const std::string& user_email) OVERRIDE {}
537  virtual void StopSession() OVERRIDE {}
538  virtual void StartDeviceWipe() OVERRIDE {}
539  virtual void RequestLockScreen() OVERRIDE {
540    FOR_EACH_OBSERVER(Observer, observers_, LockScreen());
541  }
542  virtual void NotifyLockScreenShown() OVERRIDE {
543    FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked());
544  }
545  virtual void RequestUnlockScreen() OVERRIDE {
546    FOR_EACH_OBSERVER(Observer, observers_, UnlockScreen());
547  }
548  virtual void NotifyLockScreenDismissed() OVERRIDE {
549    FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked());
550  }
551  virtual void RetrieveActiveSessions(
552      const ActiveSessionsCallback& callback) OVERRIDE {}
553  virtual void RetrieveDevicePolicy(
554      const RetrievePolicyCallback& callback) OVERRIDE {
555    callback.Run(device_policy_);
556  }
557  virtual void RetrievePolicyForUser(
558      const std::string& username,
559      const RetrievePolicyCallback& callback) OVERRIDE {
560    callback.Run(user_policies_[username]);
561  }
562  virtual void RetrieveDeviceLocalAccountPolicy(
563      const std::string& account_name,
564      const RetrievePolicyCallback& callback) OVERRIDE {
565    callback.Run(user_policies_[account_name]);
566  }
567  virtual void StoreDevicePolicy(const std::string& policy_blob,
568                                 const StorePolicyCallback& callback) OVERRIDE {
569    device_policy_ = policy_blob;
570    callback.Run(true);
571  }
572  virtual void StorePolicyForUser(
573      const std::string& username,
574      const std::string& policy_blob,
575      const std::string& policy_key,
576      const StorePolicyCallback& callback) OVERRIDE {
577    if (policy_key.empty()) {
578      user_policies_[username] = policy_blob;
579      callback.Run(true);
580      return;
581    }
582    // The session manager writes the user policy key to a well-known
583    // location. Do the same with the stub impl, so that user policy works and
584    // can be tested on desktop builds.
585    // TODO(joaodasilva): parse the PolicyFetchResponse in |policy_blob| to get
586    // the policy key directly, after moving the policy protobufs to a top-level
587    // directory. The |policy_key| argument to this method can then be removed.
588    // http://crbug.com/240269
589    base::FilePath key_path;
590    if (!PathService::Get(chromeos::DIR_USER_POLICY_KEYS, &key_path)) {
591      callback.Run(false);
592      return;
593    }
594    const std::string sanitized =
595        CryptohomeClient::GetStubSanitizedUsername(username);
596    key_path = key_path.AppendASCII(sanitized).AppendASCII("policy.pub");
597    // Assume that the key write is successful.
598    user_policies_[username] = policy_blob;
599    base::WorkerPool::PostTaskAndReply(
600        FROM_HERE,
601        base::Bind(&SessionManagerClientStubImpl::StoreFileInBackground,
602                   key_path, policy_key),
603        base::Bind(callback, true),
604        false);
605  }
606  virtual void StoreDeviceLocalAccountPolicy(
607      const std::string& account_name,
608      const std::string& policy_blob,
609      const StorePolicyCallback& callback) OVERRIDE {
610    user_policies_[account_name] = policy_blob;
611    callback.Run(true);
612  }
613  virtual void SetFlagsForUser(const std::string& username,
614                               const std::vector<std::string>& flags) OVERRIDE {
615  }
616
617  static void StoreFileInBackground(const base::FilePath& path,
618                                    const std::string& data) {
619    const int size = static_cast<int>(data.size());
620    if (!file_util::CreateDirectory(path.DirName()) ||
621        file_util::WriteFile(path, data.data(), size) != size) {
622      LOG(WARNING) << "Failed to write policy key to " << path.value();
623    }
624  }
625
626 private:
627  ObserverList<Observer> observers_;
628  std::string device_policy_;
629  std::map<std::string, std::string> user_policies_;
630
631  DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl);
632};
633
634SessionManagerClient::SessionManagerClient() {
635}
636
637SessionManagerClient::~SessionManagerClient() {
638}
639
640SessionManagerClient* SessionManagerClient::Create(
641    DBusClientImplementationType type,
642    dbus::Bus* bus) {
643  if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
644    return new SessionManagerClientImpl(bus);
645  DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
646  return new SessionManagerClientStubImpl();
647}
648
649}  // namespace chromeos
650