15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/session_manager_client.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include <map>
8a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
11a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/file_util.h"
12a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/files/file_path.h"
13a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/location.h"
14a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/path_service.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
16a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/threading/worker_pool.h"
17a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chromeos/chromeos_paths.h"
18bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "chromeos/dbus/blocking_method_caller.h"
19a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chromeos/dbus/cryptohome_client.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/bus.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/message.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_path.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_proxy.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The SessionManagerClient implementation used in production.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SessionManagerClientImpl : public SessionManagerClient {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
31424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SessionManagerClientImpl()
32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      : session_manager_proxy_(NULL),
33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        weak_ptr_factory_(this) {}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SessionManagerClientImpl() {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SessionManagerClient overrides:
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void AddObserver(Observer* observer) OVERRIDE {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observers_.AddObserver(observer);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RemoveObserver(Observer* observer) OVERRIDE {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observers_.RemoveObserver(observer);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool HasObserver(Observer* observer) OVERRIDE {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return observers_.HasObserver(observer);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void EmitLoginPromptReady() OVERRIDE {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleMethodCallToSessionManager(
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        login_manager::kSessionManagerEmitLoginPromptReady);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void EmitLoginPromptVisible() OVERRIDE {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleMethodCallToSessionManager(
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        login_manager::kSessionManagerEmitLoginPromptVisible);
59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FOR_EACH_OBSERVER(Observer, observers_, EmitLoginPromptVisibleCalled());
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 login_manager::kSessionManagerRestartJob);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendInt32(pid);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString(command_line);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    session_manager_proxy_->CallMethod(
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&SessionManagerClientImpl::OnRestartJob,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StartSession(const std::string& user_email) OVERRIDE {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 login_manager::kSessionManagerStartSession);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString(user_email);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString("");  // Unique ID is deprecated
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    session_manager_proxy_->CallMethod(
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&SessionManagerClientImpl::OnStartSession,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StopSession() OVERRIDE {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 login_manager::kSessionManagerStopSession);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString("");  // Unique ID is deprecated
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    session_manager_proxy_->CallMethod(
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&SessionManagerClientImpl::OnStopSession,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StartDeviceWipe() OVERRIDE {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 login_manager::kSessionManagerStartDeviceWipe);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    session_manager_proxy_->CallMethod(
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&SessionManagerClientImpl::OnDeviceWipe,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RequestLockScreen() OVERRIDE {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleMethodCallToSessionManager(login_manager::kSessionManagerLockScreen);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void NotifyLockScreenShown() OVERRIDE {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleMethodCallToSessionManager(
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        login_manager::kSessionManagerHandleLockScreenShown);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void NotifyLockScreenDismissed() OVERRIDE {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleMethodCallToSessionManager(
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        login_manager::kSessionManagerHandleLockScreenDismissed);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void RetrieveActiveSessions(
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      const ActiveSessionsCallback& callback) OVERRIDE {
12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    dbus::MethodCall method_call(
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        login_manager::kSessionManagerInterface,
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        login_manager::kSessionManagerRetrieveActiveSessions);
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    session_manager_proxy_->CallMethod(
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        &method_call,
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        base::Bind(&SessionManagerClientImpl::OnRetrieveActiveSessions,
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                   login_manager::kSessionManagerRetrieveActiveSessions,
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                   callback));
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RetrieveDevicePolicy(
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const RetrievePolicyCallback& callback) OVERRIDE {
141a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
142a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                 login_manager::kSessionManagerRetrievePolicy);
143a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    session_manager_proxy_->CallMethod(
144a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        &method_call,
145a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
146a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        base::Bind(&SessionManagerClientImpl::OnRetrievePolicy,
147a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
148a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                   login_manager::kSessionManagerRetrievePolicy,
149a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                   callback));
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
152a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  virtual void RetrievePolicyForUser(
153a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      const std::string& username,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const RetrievePolicyCallback& callback) OVERRIDE {
155a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CallRetrievePolicyByUsername(
156a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        login_manager::kSessionManagerRetrievePolicyForUser,
157a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        username,
158a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        callback);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
161bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  virtual std::string BlockingRetrievePolicyForUser(
162bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      const std::string& username) OVERRIDE {
163bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    dbus::MethodCall method_call(
164bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch        login_manager::kSessionManagerInterface,
165bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch        login_manager::kSessionManagerRetrievePolicyForUser);
166bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    dbus::MessageWriter writer(&method_call);
167bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    writer.AppendString(username);
168bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    scoped_ptr<dbus::Response> response =
169424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        blocking_method_caller_->CallMethodAndBlock(&method_call);
170bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    std::string policy;
171bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    ExtractString(login_manager::kSessionManagerRetrievePolicyForUser,
172bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                  response.get(),
173bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                  &policy);
174bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    return policy;
175bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  }
176bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void RetrieveDeviceLocalAccountPolicy(
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& account_name,
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const RetrievePolicyCallback& callback) OVERRIDE {
180a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CallRetrievePolicyByUsername(
181a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        login_manager::kSessionManagerRetrieveDeviceLocalAccountPolicy,
182a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        account_name,
183a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        callback);
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StoreDevicePolicy(const std::string& policy_blob,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const StorePolicyCallback& callback) OVERRIDE {
188a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
189a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                 login_manager::kSessionManagerStorePolicy);
190a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    dbus::MessageWriter writer(&method_call);
191a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // static_cast does not work due to signedness.
192a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    writer.AppendArrayOfBytes(
193a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size());
194a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    session_manager_proxy_->CallMethod(
195a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        &method_call,
196a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
197a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        base::Bind(&SessionManagerClientImpl::OnStorePolicy,
198a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
199a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                   login_manager::kSessionManagerStorePolicy,
200a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                   callback));
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
203a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  virtual void StorePolicyForUser(
204a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      const std::string& username,
205a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      const std::string& policy_blob,
206a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      const std::string& ignored_policy_key,
207a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      const StorePolicyCallback& callback) OVERRIDE {
208a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CallStorePolicyByUsername(login_manager::kSessionManagerStorePolicyForUser,
209a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                              username,
210a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                              policy_blob,
211a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                              callback);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void StoreDeviceLocalAccountPolicy(
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& account_name,
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& policy_blob,
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const StorePolicyCallback& callback) OVERRIDE {
218a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CallStorePolicyByUsername(
219a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        login_manager::kSessionManagerStoreDeviceLocalAccountPolicy,
220a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        account_name,
221a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        policy_blob,
222a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        callback);
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void SetFlagsForUser(const std::string& username,
2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               const std::vector<std::string>& flags) OVERRIDE {
2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                 login_manager::kSessionManagerSetFlagsForUser);
2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    writer.AppendString(username);
2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    writer.AppendArrayOfStrings(flags);
2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    session_manager_proxy_->CallMethod(
2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        &method_call,
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
2357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        dbus::ObjectProxy::EmptyResponseCallback());
2367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) protected:
239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void Init(dbus::Bus* bus) OVERRIDE {
240424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    session_manager_proxy_ = bus->GetObjectProxy(
241424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        login_manager::kSessionManagerServiceName,
242424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        dbus::ObjectPath(login_manager::kSessionManagerServicePath));
243424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    blocking_method_caller_.reset(
244424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        new BlockingMethodCaller(bus, session_manager_proxy_));
245424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
246424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Signals emitted on Chromium's interface.  Many of these ought to be
247424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // method calls instead.
248424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    session_manager_proxy_->ConnectToSignal(
249424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        chromium::kChromiumInterface,
250424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        chromium::kOwnerKeySetSignal,
251424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        base::Bind(&SessionManagerClientImpl::OwnerKeySetReceived,
252424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()),
253424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        base::Bind(&SessionManagerClientImpl::SignalConnected,
254424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
255424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    session_manager_proxy_->ConnectToSignal(
256424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        chromium::kChromiumInterface,
257424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        chromium::kPropertyChangeCompleteSignal,
258424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        base::Bind(&SessionManagerClientImpl::PropertyChangeCompleteReceived,
259424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()),
260424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        base::Bind(&SessionManagerClientImpl::SignalConnected,
261424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
262424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    session_manager_proxy_->ConnectToSignal(
263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        chromium::kChromiumInterface,
264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        chromium::kLockScreenSignal,
265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        base::Bind(&SessionManagerClientImpl::ScreenLockReceived,
266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()),
267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        base::Bind(&SessionManagerClientImpl::SignalConnected,
268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
269424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    session_manager_proxy_->ConnectToSignal(
270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        chromium::kChromiumInterface,
271424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        chromium::kLivenessRequestedSignal,
272424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        base::Bind(&SessionManagerClientImpl::LivenessRequestedReceived,
273424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()),
274424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        base::Bind(&SessionManagerClientImpl::SignalConnected,
275424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
277424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Signals emitted on the session manager's interface.
278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    session_manager_proxy_->ConnectToSignal(
279424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        login_manager::kSessionManagerInterface,
280424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        login_manager::kScreenIsLockedSignal,
281424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        base::Bind(&SessionManagerClientImpl::ScreenIsLockedReceived,
282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()),
283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        base::Bind(&SessionManagerClientImpl::SignalConnected,
284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    session_manager_proxy_->ConnectToSignal(
286424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        login_manager::kSessionManagerInterface,
287424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        login_manager::kScreenIsUnlockedSignal,
288424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        base::Bind(&SessionManagerClientImpl::ScreenIsUnlockedReceived,
289424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()),
290424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        base::Bind(&SessionManagerClientImpl::SignalConnected,
291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Makes a method call to the session manager with no arguments and no
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // response.
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SimpleMethodCallToSessionManager(const std::string& method_name) {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 method_name);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    session_manager_proxy_->CallMethod(
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::EmptyResponseCallback());
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
306a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Helper for RetrieveDeviceLocalAccountPolicy and RetrievePolicyForUser.
307a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  void CallRetrievePolicyByUsername(const std::string& method_name,
308a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                    const std::string& username,
309a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                    const RetrievePolicyCallback& callback) {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 method_name);
312a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    dbus::MessageWriter writer(&method_call);
313a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    writer.AppendString(username);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    session_manager_proxy_->CallMethod(
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
317a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        base::Bind(
318a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            &SessionManagerClientImpl::OnRetrievePolicy,
319a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            weak_ptr_factory_.GetWeakPtr(),
320a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            method_name,
321a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            callback));
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
324a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  void CallStorePolicyByUsername(const std::string& method_name,
325a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                 const std::string& username,
326a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                 const std::string& policy_blob,
327a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                 const StorePolicyCallback& callback) {
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 method_name);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
331a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    writer.AppendString(username);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // static_cast does not work due to signedness.
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendArrayOfBytes(
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size());
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    session_manager_proxy_->CallMethod(
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
338a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        base::Bind(
339a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            &SessionManagerClientImpl::OnStorePolicy,
340a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            weak_ptr_factory_.GetWeakPtr(),
341a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            method_name,
342a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            callback));
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when kSessionManagerRestartJob method is complete.
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnRestartJob(dbus::Response* response) {
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG_IF(ERROR, !response)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << "Failed to call "
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << login_manager::kSessionManagerRestartJob;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when kSessionManagerStartSession method is complete.
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnStartSession(dbus::Response* response) {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG_IF(ERROR, !response)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << "Failed to call "
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << login_manager::kSessionManagerStartSession;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when kSessionManagerStopSession method is complete.
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnStopSession(dbus::Response* response) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG_IF(ERROR, !response)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << "Failed to call "
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << login_manager::kSessionManagerStopSession;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when kSessionManagerStopSession method is complete.
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnDeviceWipe(dbus::Response* response) {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG_IF(ERROR, !response)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << "Failed to call "
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << login_manager::kSessionManagerStartDeviceWipe;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Called when kSessionManagerRetrieveActiveSessions method is complete.
37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void OnRetrieveActiveSessions(const std::string& method_name,
37590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                const ActiveSessionsCallback& callback,
37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                dbus::Response* response) {
37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ActiveSessionsMap sessions;
37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    bool success = false;
37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!response) {
38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      LOG(ERROR) << "Failed to call " << method_name;
38190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      callback.Run(sessions, success);
38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
38490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
38590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    dbus::MessageReader reader(response);
38690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    dbus::MessageReader array_reader(NULL);
38790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
38890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!reader.PopArray(&array_reader)) {
38990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      LOG(ERROR) << method_name << " response is incorrect: "
39090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 << response->ToString();
39190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    } else {
39290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      while (array_reader.HasMoreData()) {
39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        dbus::MessageReader dict_entry_reader(NULL);
39490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        std::string key;
39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        std::string value;
39690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        if (!array_reader.PopDictEntry(&dict_entry_reader) ||
39790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            !dict_entry_reader.PopString(&key) ||
39890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            !dict_entry_reader.PopString(&value)) {
39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          LOG(ERROR) << method_name << " response is incorrect: "
40090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     << response->ToString();
40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        } else {
40290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          sessions[key] = value;
40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        }
40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      }
40590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      success = true;
40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
40790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    callback.Run(sessions, success);
40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
40990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
410bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  void ExtractString(const std::string& method_name,
411bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                     dbus::Response* response,
412bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                     std::string* extracted) {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to call " << method_name;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageReader reader(response);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8* values = NULL;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t length = 0;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!reader.PopArrayOfBytes(&values, &length)) {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Invalid response: " << response->ToString();
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // static_cast does not work due to signedness.
425bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    extracted->assign(reinterpret_cast<char*>(values), length);
426bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  }
427bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
428bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  // Called when kSessionManagerRetrievePolicy or
429bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  // kSessionManagerRetrievePolicyForUser method is complete.
430bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  void OnRetrievePolicy(const std::string& method_name,
431bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                        const RetrievePolicyCallback& callback,
432bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                        dbus::Response* response) {
433bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    std::string serialized_proto;
434bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    ExtractString(method_name, response, &serialized_proto);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(serialized_proto);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
438a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Called when kSessionManagerStorePolicy or kSessionManagerStorePolicyForUser
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // method is complete.
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnStorePolicy(const std::string& method_name,
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const StorePolicyCallback& callback,
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     dbus::Response* response) {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool success = false;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to call " << method_name;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dbus::MessageReader reader(response);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!reader.PopBool(&success))
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LOG(ERROR) << "Invalid response: " << response->ToString();
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(success);
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the owner key set signal is received.
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OwnerKeySetReceived(dbus::Signal* signal) {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageReader reader(signal);
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string result_string;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!reader.PopString(&result_string)) {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Invalid signal: " << signal->ToString();
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const bool success = StartsWithASCII(result_string, "success", false);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FOR_EACH_OBSERVER(Observer, observers_, OwnerKeySet(success));
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the property change complete signal is received.
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PropertyChangeCompleteReceived(dbus::Signal* signal) {
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageReader reader(signal);
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string result_string;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!reader.PopString(&result_string)) {
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Invalid signal: " << signal->ToString();
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const bool success = StartsWithASCII(result_string, "success", false);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FOR_EACH_OBSERVER(Observer, observers_, PropertyChangeComplete(success));
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ScreenLockReceived(dbus::Signal* signal) {
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FOR_EACH_OBSERVER(Observer, observers_, LockScreen());
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void LivenessRequestedReceived(dbus::Signal* signal) {
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SimpleMethodCallToSessionManager(
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        login_manager::kSessionManagerHandleLivenessConfirmed);
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ScreenIsLockedReceived(dbus::Signal* signal) {
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked());
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ScreenIsUnlockedReceived(dbus::Signal* signal) {
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked());
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the object is connected to the signal.
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SignalConnected(const std::string& interface_name,
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const std::string& signal_name,
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       bool success) {
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG_IF(ERROR, !success) << "Failed to connect to " << signal_name;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dbus::ObjectProxy* session_manager_proxy_;
503424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  scoped_ptr<BlockingMethodCaller> blocking_method_caller_;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObserverList<Observer> observers_;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: This should remain the last member so it'll be destroyed and
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // invalidate its weak pointers before any other members are destroyed.
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<SessionManagerClientImpl> weak_ptr_factory_;
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SessionManagerClientImpl);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The SessionManagerClient implementation used on Linux desktop,
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which does nothing.
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SessionManagerClientStubImpl : public SessionManagerClient {
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
517424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SessionManagerClientStubImpl() {}
518424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual ~SessionManagerClientStubImpl() {}
519424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
520424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // SessionManagerClient overrides
521424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void Init(dbus::Bus* bus) OVERRIDE {
522a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // Make sure that there are no keys left over from a previous browser run.
523a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    base::FilePath user_policy_key_dir;
524a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (PathService::Get(chromeos::DIR_USER_POLICY_KEYS,
525a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                         &user_policy_key_dir)) {
526a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      base::WorkerPool::PostTask(
527a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          FROM_HERE,
5287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          base::Bind(base::IgnoreResult(&base::DeleteFile),
529a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                     user_policy_key_dir, true),
530a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          false);
531a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
532a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void AddObserver(Observer* observer) OVERRIDE {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observers_.AddObserver(observer);
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RemoveObserver(Observer* observer) OVERRIDE {
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observers_.RemoveObserver(observer);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool HasObserver(Observer* observer) OVERRIDE {
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return observers_.HasObserver(observer);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void EmitLoginPromptReady() OVERRIDE {}
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void EmitLoginPromptVisible() OVERRIDE {}
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {}
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StartSession(const std::string& user_email) OVERRIDE {}
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StopSession() OVERRIDE {}
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StartDeviceWipe() OVERRIDE {}
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RequestLockScreen() OVERRIDE {
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FOR_EACH_OBSERVER(Observer, observers_, LockScreen());
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NotifyLockScreenShown() OVERRIDE {
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked());
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NotifyLockScreenDismissed() OVERRIDE {
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked());
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
55890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void RetrieveActiveSessions(
55990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      const ActiveSessionsCallback& callback) OVERRIDE {}
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RetrieveDevicePolicy(
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const RetrievePolicyCallback& callback) OVERRIDE {
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(device_policy_);
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
564a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  virtual void RetrievePolicyForUser(
565a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      const std::string& username,
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const RetrievePolicyCallback& callback) OVERRIDE {
567a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    callback.Run(user_policies_[username]);
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
569bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  virtual std::string BlockingRetrievePolicyForUser(
570bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      const std::string& username) OVERRIDE {
571bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    return user_policies_[username];
572bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  }
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void RetrieveDeviceLocalAccountPolicy(
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& account_name,
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const RetrievePolicyCallback& callback) OVERRIDE {
576a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    callback.Run(user_policies_[account_name]);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StoreDevicePolicy(const std::string& policy_blob,
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const StorePolicyCallback& callback) OVERRIDE {
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_policy_ = policy_blob;
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(true);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
583a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  virtual void StorePolicyForUser(
584a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      const std::string& username,
585a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      const std::string& policy_blob,
586a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      const std::string& policy_key,
587a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      const StorePolicyCallback& callback) OVERRIDE {
588a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (policy_key.empty()) {
589a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      user_policies_[username] = policy_blob;
590a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      callback.Run(true);
591a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      return;
592a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
593a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // The session manager writes the user policy key to a well-known
594a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // location. Do the same with the stub impl, so that user policy works and
595a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // can be tested on desktop builds.
596a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // TODO(joaodasilva): parse the PolicyFetchResponse in |policy_blob| to get
597a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // the policy key directly, after moving the policy protobufs to a top-level
598a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // directory. The |policy_key| argument to this method can then be removed.
599a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // http://crbug.com/240269
600a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    base::FilePath key_path;
601a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (!PathService::Get(chromeos::DIR_USER_POLICY_KEYS, &key_path)) {
602a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      callback.Run(false);
603a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      return;
604a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
605a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const std::string sanitized =
606a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        CryptohomeClient::GetStubSanitizedUsername(username);
607a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    key_path = key_path.AppendASCII(sanitized).AppendASCII("policy.pub");
608a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // Assume that the key write is successful.
609a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    user_policies_[username] = policy_blob;
610a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    base::WorkerPool::PostTaskAndReply(
611a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        FROM_HERE,
612a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        base::Bind(&SessionManagerClientStubImpl::StoreFileInBackground,
613a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                   key_path, policy_key),
614a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        base::Bind(callback, true),
615a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        false);
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void StoreDeviceLocalAccountPolicy(
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& account_name,
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& policy_blob,
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const StorePolicyCallback& callback) OVERRIDE {
621a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    user_policies_[account_name] = policy_blob;
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(true);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void SetFlagsForUser(const std::string& username,
6257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               const std::vector<std::string>& flags) OVERRIDE {
6267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
628a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  static void StoreFileInBackground(const base::FilePath& path,
629a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                    const std::string& data) {
630a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const int size = static_cast<int>(data.size());
631a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!base::CreateDirectory(path.DirName()) ||
632a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        file_util::WriteFile(path, data.data(), size) != size) {
633a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      LOG(WARNING) << "Failed to write policy key to " << path.value();
634a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
635a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
636a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObserverList<Observer> observers_;
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string device_policy_;
640a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::map<std::string, std::string> user_policies_;
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SessionManagerClient::SessionManagerClient() {
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SessionManagerClient::~SessionManagerClient() {
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SessionManagerClient* SessionManagerClient::Create(
652424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    DBusClientImplementationType type) {
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
654424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return new SessionManagerClientImpl();
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new SessionManagerClientStubImpl();
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
660