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