Upstream version 10.38.208.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/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     bool first_run = false;
529     if (!response) {
530       LOG(ERROR) << "Failed to call "
531                  << login_manager::kSessionManagerStartSession;
532     } else {
533       dbus::MessageReader reader(response);
534       dbus::MessageReader array_reader(NULL);
535
536       if (!reader.PopArray(&array_reader)) {
537         LOG(ERROR) << "Bad response: " << response->ToString();
538       } else {
539         while (array_reader.HasMoreData()) {
540           const uint8* data = NULL;
541           size_t size = 0;
542           if (!array_reader.PopArrayOfBytes(&data, &size)) {
543             LOG(ERROR) << "Bad response: " << response->ToString();
544             state_keys.clear();
545             break;
546           }
547           state_keys.push_back(
548               std::string(reinterpret_cast<const char*>(data), size));
549         }
550       }
551       if (!reader.PopBool(&first_run)) {
552         // TODO(tnagel): After 2014-11-19 turn this warning into an error.
553         LOG(WARNING) << "Chrome OS is too old. Defaulting to first_run=false.";
554       }
555     }
556
557     if (!callback.is_null())
558       callback.Run(state_keys, first_run);
559   }
560
561
562   dbus::ObjectProxy* session_manager_proxy_;
563   scoped_ptr<BlockingMethodCaller> blocking_method_caller_;
564   ObserverList<Observer> observers_;
565
566   // Note: This should remain the last member so it'll be destroyed and
567   // invalidate its weak pointers before any other members are destroyed.
568   base::WeakPtrFactory<SessionManagerClientImpl> weak_ptr_factory_;
569
570   DISALLOW_COPY_AND_ASSIGN(SessionManagerClientImpl);
571 };
572
573 // The SessionManagerClient implementation used on Linux desktop,
574 // which does nothing.
575 class SessionManagerClientStubImpl : public SessionManagerClient {
576  public:
577   SessionManagerClientStubImpl() : delegate_(NULL) {}
578   virtual ~SessionManagerClientStubImpl() {}
579
580   // SessionManagerClient overrides
581   virtual void Init(dbus::Bus* bus) OVERRIDE {}
582   virtual void SetStubDelegate(StubDelegate* delegate) OVERRIDE {
583     delegate_ = delegate;
584   }
585   virtual void AddObserver(Observer* observer) OVERRIDE {
586     observers_.AddObserver(observer);
587   }
588   virtual void RemoveObserver(Observer* observer) OVERRIDE {
589     observers_.RemoveObserver(observer);
590   }
591   virtual bool HasObserver(Observer* observer) OVERRIDE {
592     return observers_.HasObserver(observer);
593   }
594   virtual void EmitLoginPromptVisible() OVERRIDE {}
595   virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {}
596   virtual void StartSession(const std::string& user_email) OVERRIDE {}
597   virtual void StopSession() OVERRIDE {}
598   virtual void StartDeviceWipe() OVERRIDE {}
599   virtual void RequestLockScreen() OVERRIDE {
600     if (delegate_)
601       delegate_->LockScreenForStub();
602   }
603   virtual void NotifyLockScreenShown() OVERRIDE {
604     FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked());
605   }
606   virtual void NotifyLockScreenDismissed() OVERRIDE {
607     FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked());
608   }
609   virtual void RetrieveActiveSessions(
610       const ActiveSessionsCallback& callback) OVERRIDE {}
611   virtual void RetrieveDevicePolicy(
612       const RetrievePolicyCallback& callback) OVERRIDE {
613     base::FilePath owner_key_path;
614     if (!PathService::Get(chromeos::FILE_OWNER_KEY, &owner_key_path)) {
615       callback.Run("");
616       return;
617     }
618     base::FilePath device_policy_path =
619         owner_key_path.DirName().AppendASCII("stub_device_policy");
620     base::PostTaskAndReplyWithResult(
621         base::WorkerPool::GetTaskRunner(false),
622         FROM_HERE,
623         base::Bind(&GetFileContent, device_policy_path),
624         callback);
625   }
626   virtual void RetrievePolicyForUser(
627       const std::string& username,
628       const RetrievePolicyCallback& callback) OVERRIDE {
629     base::PostTaskAndReplyWithResult(
630         base::WorkerPool::GetTaskRunner(false),
631         FROM_HERE,
632         base::Bind(&GetFileContent, GetUserFilePath(username, "stub_policy")),
633         callback);
634   }
635   virtual std::string BlockingRetrievePolicyForUser(
636       const std::string& username) OVERRIDE {
637     return GetFileContent(GetUserFilePath(username, "stub_policy"));
638   }
639   virtual void RetrieveDeviceLocalAccountPolicy(
640       const std::string& account_name,
641       const RetrievePolicyCallback& callback) OVERRIDE {
642     RetrievePolicyForUser(account_name, callback);
643   }
644   virtual void StoreDevicePolicy(const std::string& policy_blob,
645                                  const StorePolicyCallback& callback) OVERRIDE {
646     enterprise_management::PolicyFetchResponse response;
647     base::FilePath owner_key_path;
648     if (!response.ParseFromString(policy_blob) ||
649         !PathService::Get(chromeos::FILE_OWNER_KEY, &owner_key_path)) {
650       callback.Run(false);
651       return;
652     }
653
654     if (response.has_new_public_key()) {
655       base::WorkerPool::PostTask(
656           FROM_HERE,
657           base::Bind(&StoreFile, owner_key_path, response.new_public_key()),
658           false);
659     }
660
661     // Chrome will attempt to retrieve the device policy right after storing
662     // during enrollment, so make sure it's written before signaling
663     // completion.
664     // Note also that the owner key will be written before the device policy,
665     // if it was present in the blob.
666     base::FilePath device_policy_path =
667         owner_key_path.DirName().AppendASCII("stub_device_policy");
668     base::WorkerPool::PostTaskAndReply(
669         FROM_HERE,
670         base::Bind(&StoreFile, device_policy_path, policy_blob),
671         base::Bind(callback, true),
672         false);
673   }
674   virtual void StorePolicyForUser(
675       const std::string& username,
676       const std::string& policy_blob,
677       const StorePolicyCallback& callback) OVERRIDE {
678     // The session manager writes the user policy key to a well-known
679     // location. Do the same with the stub impl, so that user policy works and
680     // can be tested on desktop builds.
681     enterprise_management::PolicyFetchResponse response;
682     if (!response.ParseFromString(policy_blob)) {
683       callback.Run(false);
684       return;
685     }
686
687     if (response.has_new_public_key()) {
688       base::FilePath key_path = GetUserFilePath(username, "policy.pub");
689       base::WorkerPool::PostTask(
690           FROM_HERE,
691           base::Bind(&StoreFile, key_path, response.new_public_key()),
692           false);
693     }
694
695     // This file isn't read directly by Chrome, but is used by this class to
696     // reload the user policy across restarts.
697     base::FilePath stub_policy_path = GetUserFilePath(username, "stub_policy");
698     base::WorkerPool::PostTaskAndReply(
699         FROM_HERE,
700         base::Bind(&StoreFile, stub_policy_path, policy_blob),
701         base::Bind(callback, true),
702         false);
703   }
704   virtual void StoreDeviceLocalAccountPolicy(
705       const std::string& account_name,
706       const std::string& policy_blob,
707       const StorePolicyCallback& callback) OVERRIDE {
708     StorePolicyForUser(account_name, policy_blob, callback);
709   }
710   virtual void SetFlagsForUser(const std::string& username,
711                                const std::vector<std::string>& flags) OVERRIDE {
712   }
713
714   virtual void GetServerBackedStateKeys(const StateKeysCallback& callback)
715       OVERRIDE {
716     std::vector<std::string> state_keys;
717     for (int i = 0; i < 5; ++i)
718       state_keys.push_back(crypto::SHA256HashString(base::IntToString(i)));
719
720     if (!callback.is_null())
721       callback.Run(state_keys, false);
722   }
723
724  private:
725   StubDelegate* delegate_;  // Weak pointer; may be NULL.
726   ObserverList<Observer> observers_;
727   std::string device_policy_;
728
729   DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl);
730 };
731
732 SessionManagerClient::SessionManagerClient() {
733 }
734
735 SessionManagerClient::~SessionManagerClient() {
736 }
737
738 SessionManagerClient* SessionManagerClient::Create(
739     DBusClientImplementationType type) {
740   if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
741     return new SessionManagerClientImpl();
742   DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
743   return new SessionManagerClientStubImpl();
744 }
745
746 }  // namespace chromeos