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