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