Pepper: Fix crash on allocation failure.
[chromium-blink-merge.git] / chromeos / dbus / session_manager_client.cc
blobbfa9aa448dc235fd1e0a03a494e77cef449ecdae
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.
5 #include "chromeos/dbus/session_manager_client.h"
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"
28 namespace chromeos {
30 namespace {
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);
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;
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();
62 } // namespace
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) {}
71 virtual ~SessionManagerClientImpl() {
74 // SessionManagerClient overrides:
75 virtual void SetStubDelegate(StubDelegate* delegate) OVERRIDE {
76 // Do nothing; this isn't a stub implementation.
79 virtual void AddObserver(Observer* observer) OVERRIDE {
80 observers_.AddObserver(observer);
83 virtual void RemoveObserver(Observer* observer) OVERRIDE {
84 observers_.RemoveObserver(observer);
87 virtual bool HasObserver(Observer* observer) OVERRIDE {
88 return observers_.HasObserver(observer);
91 virtual void EmitLoginPromptVisible() OVERRIDE {
92 SimpleMethodCallToSessionManager(
93 login_manager::kSessionManagerEmitLoginPromptVisible);
94 FOR_EACH_OBSERVER(Observer, observers_, EmitLoginPromptVisibleCalled());
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()));
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()));
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()));
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()));
145 virtual void RequestLockScreen() OVERRIDE {
146 SimpleMethodCallToSessionManager(login_manager::kSessionManagerLockScreen);
149 virtual void NotifyLockScreenShown() OVERRIDE {
150 SimpleMethodCallToSessionManager(
151 login_manager::kSessionManagerHandleLockScreenShown);
154 virtual void NotifyLockScreenDismissed() OVERRIDE {
155 SimpleMethodCallToSessionManager(
156 login_manager::kSessionManagerHandleLockScreenDismissed);
159 virtual void RetrieveActiveSessions(
160 const ActiveSessionsCallback& callback) OVERRIDE {
161 dbus::MethodCall method_call(
162 login_manager::kSessionManagerInterface,
163 login_manager::kSessionManagerRetrieveActiveSessions);
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));
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));
187 virtual void RetrievePolicyForUser(
188 const std::string& username,
189 const RetrievePolicyCallback& callback) OVERRIDE {
190 CallRetrievePolicyByUsername(
191 login_manager::kSessionManagerRetrievePolicyForUser,
192 username,
193 callback);
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;
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);
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));
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);
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);
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());
272 virtual void GetServerBackedStateKeys(const StateKeysCallback& callback)
273 OVERRIDE {
274 dbus::MethodCall method_call(
275 login_manager::kSessionManagerInterface,
276 login_manager::kSessionManagerGetServerBackedStateKeys);
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));
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_));
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()));
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());
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));
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));
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;
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;
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;
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;
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;
416 dbus::MessageReader reader(response);
417 dbus::MessageReader array_reader(NULL);
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;
436 success = true;
438 callback.Run(sessions, success);
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;
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;
455 // static_cast does not work due to signedness.
456 extracted->assign(reinterpret_cast<const char*>(values), length);
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);
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();
482 callback.Run(success);
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;
493 const bool success = StartsWithASCII(result_string, "success", false);
494 FOR_EACH_OBSERVER(Observer, observers_, OwnerKeySet(success));
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;
505 const bool success = StartsWithASCII(result_string, "success", false);
506 FOR_EACH_OBSERVER(Observer, observers_, PropertyChangeComplete(success));
509 void ScreenIsLockedReceived(dbus::Signal* signal) {
510 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked());
513 void ScreenIsUnlockedReceived(dbus::Signal* signal) {
514 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked());
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;
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 if (!response) {
529 LOG(ERROR) << "Failed to call "
530 << login_manager::kSessionManagerStartSession;
531 } else {
532 dbus::MessageReader reader(response);
533 dbus::MessageReader array_reader(NULL);
535 if (!reader.PopArray(&array_reader)) {
536 LOG(ERROR) << "Bad response: " << response->ToString();
537 } else {
538 while (array_reader.HasMoreData()) {
539 const uint8* data = NULL;
540 size_t size = 0;
541 if (!array_reader.PopArrayOfBytes(&data, &size)) {
542 LOG(ERROR) << "Bad response: " << response->ToString();
543 state_keys.clear();
544 break;
546 state_keys.push_back(
547 std::string(reinterpret_cast<const char*>(data), size));
552 if (!callback.is_null())
553 callback.Run(state_keys);
557 dbus::ObjectProxy* session_manager_proxy_;
558 scoped_ptr<BlockingMethodCaller> blocking_method_caller_;
559 ObserverList<Observer> observers_;
561 // Note: This should remain the last member so it'll be destroyed and
562 // invalidate its weak pointers before any other members are destroyed.
563 base::WeakPtrFactory<SessionManagerClientImpl> weak_ptr_factory_;
565 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientImpl);
568 // The SessionManagerClient implementation used on Linux desktop,
569 // which does nothing.
570 class SessionManagerClientStubImpl : public SessionManagerClient {
571 public:
572 SessionManagerClientStubImpl() : delegate_(NULL) {}
573 virtual ~SessionManagerClientStubImpl() {}
575 // SessionManagerClient overrides
576 virtual void Init(dbus::Bus* bus) OVERRIDE {
577 // Make sure that there are no keys left over from a previous browser run.
578 base::FilePath user_policy_key_dir;
579 if (PathService::Get(chromeos::DIR_USER_POLICY_KEYS,
580 &user_policy_key_dir)) {
581 base::WorkerPool::PostTask(
582 FROM_HERE,
583 base::Bind(base::IgnoreResult(&base::DeleteFile),
584 user_policy_key_dir, true),
585 false);
589 virtual void SetStubDelegate(StubDelegate* delegate) OVERRIDE {
590 delegate_ = delegate;
592 virtual void AddObserver(Observer* observer) OVERRIDE {
593 observers_.AddObserver(observer);
595 virtual void RemoveObserver(Observer* observer) OVERRIDE {
596 observers_.RemoveObserver(observer);
598 virtual bool HasObserver(Observer* observer) OVERRIDE {
599 return observers_.HasObserver(observer);
601 virtual void EmitLoginPromptVisible() OVERRIDE {}
602 virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {}
603 virtual void StartSession(const std::string& user_email) OVERRIDE {}
604 virtual void StopSession() OVERRIDE {}
605 virtual void StartDeviceWipe() OVERRIDE {}
606 virtual void RequestLockScreen() OVERRIDE {
607 if (delegate_)
608 delegate_->LockScreenForStub();
610 virtual void NotifyLockScreenShown() OVERRIDE {
611 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked());
613 virtual void NotifyLockScreenDismissed() OVERRIDE {
614 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked());
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;
625 base::FilePath device_policy_path =
626 owner_key_path.DirName().AppendASCII("stub_device_policy");
627 base::PostTaskAndReplyWithResult(
628 base::WorkerPool::GetTaskRunner(false),
629 FROM_HERE,
630 base::Bind(&GetFileContent, device_policy_path),
631 callback);
633 virtual void RetrievePolicyForUser(
634 const std::string& username,
635 const RetrievePolicyCallback& callback) OVERRIDE {
636 base::PostTaskAndReplyWithResult(
637 base::WorkerPool::GetTaskRunner(false),
638 FROM_HERE,
639 base::Bind(&GetFileContent, GetUserFilePath(username, "stub_policy")),
640 callback);
642 virtual std::string BlockingRetrievePolicyForUser(
643 const std::string& username) OVERRIDE {
644 return GetFileContent(GetUserFilePath(username, "stub_policy"));
646 virtual void RetrieveDeviceLocalAccountPolicy(
647 const std::string& account_name,
648 const RetrievePolicyCallback& callback) OVERRIDE {
649 RetrievePolicyForUser(account_name, callback);
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;
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);
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);
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;
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);
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);
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);
717 virtual void SetFlagsForUser(const std::string& username,
718 const std::vector<std::string>& flags) OVERRIDE {
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)));
727 if (!callback.is_null())
728 callback.Run(state_keys);
731 private:
732 StubDelegate* delegate_; // Weak pointer; may be NULL.
733 ObserverList<Observer> observers_;
734 std::string device_policy_;
736 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl);
739 SessionManagerClient::SessionManagerClient() {
742 SessionManagerClient::~SessionManagerClient() {
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();
753 } // namespace chromeos