Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Side by Side Diff: chrome/browser/ui/ash/session_controller_client.cc

Issue 2545723003: ash: Add SessionController/Client mojo interfaces (Closed)
Patch Set: rebase, use ash_util::GetAshServiceName Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/ash/session_controller_client.h"
6
7 #include <algorithm>
8 #include <utility>
9
10 #include "ash/public/cpp/session_types.h"
11 #include "base/bind.h"
12 #include "base/logging.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
15 #include "chrome/browser/chromeos/profiles/profile_helper.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/ash/ash_util.h"
18 #include "chrome/browser/ui/ash/multi_user/user_switch_util.h"
19 #include "chrome/common/pref_names.h"
20 #include "chrome/grit/theme_resources.h"
21 #include "chromeos/dbus/dbus_thread_manager.h"
22 #include "chromeos/dbus/session_manager_client.h"
23 #include "components/prefs/pref_service.h"
24 #include "components/session_manager/core/session_manager.h"
25 #include "content/public/common/service_manager_connection.h"
26 #include "content/public/common/service_names.mojom.h"
27 #include "services/service_manager/public/cpp/connector.h"
28 #include "ui/base/resource/resource_bundle.h"
29
30 using user_manager::UserManager;
31 using user_manager::User;
32 using user_manager::UserList;
33
34 namespace {
35
36 // Limits the number of logged in users to 10 due to memory constraints.
37 constexpr uint32_t kMaxUsers = 10;
38
39 uint32_t GetSessionId(const User* user) {
40 const UserList logged_in_users = UserManager::Get()->GetLoggedInUsers();
41 // TODO(xiyuan): Update with real session id when user session tracking
42 // code is moved from UserManager to SessionManager.
43 for (size_t i = 0; i < logged_in_users.size(); ++i) {
44 if (logged_in_users[i] == user)
45 return i + 1;
46 }
47
48 NOTREACHED();
49 return 0u;
50 }
51
52 ash::mojom::UserSessionPtr UserToUserSession(const User& user) {
53 ash::mojom::UserSessionPtr session = ash::mojom::UserSession::New();
54 session->session_id = GetSessionId(&user);
55 session->type = user.GetType();
56 // TODO(xiyuan): Add type map for AccountId.
57 session->serialized_account_id = user.GetAccountId().Serialize();
58 session->display_name = base::UTF16ToUTF8(user.display_name());
59 session->display_email = user.display_email();
60
61 // TODO(xiyuan): Observe user image change and update.
62 // Tracked in http://crbug.com/670422
63 // TODO(xiyuan): Support multiple scale factor.
64 session->avatar = *user.GetImage().bitmap();
65 if (session->avatar.isNull()) {
66 session->avatar = *ResourceBundle::GetSharedInstance()
67 .GetImageSkiaNamed(IDR_PROFILE_PICTURE_LOADING)
68 ->bitmap();
69 }
70
71 return session;
72 }
73
74 void DoSwitchUser(const AccountId& account_id) {
75 UserManager::Get()->SwitchActiveUser(account_id);
76 }
77
78 } // namespace
79
80 SessionControllerClient::SessionControllerClient() : binding_(this) {
81 session_manager::SessionManager::Get()->AddObserver(this);
82 UserManager::Get()->AddSessionStateObserver(this);
83
84 ConnectToSessionControllerAndSetClient();
85 SendSessionInfoIfChanged();
86 // User sessions and their order will be sent via UserSessionStateObserver
87 // even for crash-n-restart.
88 }
89
90 SessionControllerClient::~SessionControllerClient() {
91 session_manager::SessionManager::Get()->RemoveObserver(this);
92 UserManager::Get()->RemoveSessionStateObserver(this);
93 }
94
95 void SessionControllerClient::RequestLockScreen() {
96 DoLockScreen();
97 }
98
99 void SessionControllerClient::SwitchActiveUser(
100 const std::string& serialized_account_id) {
101 // TODO(xiyuan): Add type map for AccountId.
102 AccountId account_id(EmptyAccountId());
103 if (!AccountId::Deserialize(serialized_account_id, &account_id)) {
104 LOG(ERROR) << "Bad account id for SwitchActiveUser.";
105 return;
106 }
107
108 DoSwitchActiveUser(account_id);
109 }
110
111 void SessionControllerClient::CycleActiveUser(bool next_user) {
112 DoCycleActiveUser(next_user);
113 }
114
115 void SessionControllerClient::ActiveUserChanged(const User* active_user) {
116 SendSessionInfoIfChanged();
117
118 // UserAddedToSession is not called for the primary user session so send its
119 // meta data here once.
120 if (!primary_user_session_sent_ &&
121 UserManager::Get()->GetPrimaryUser() == active_user) {
122 primary_user_session_sent_ = true;
123 SendUserSession(*active_user);
124 }
125
126 SendUserSessionOrder();
127 }
128
129 void SessionControllerClient::UserAddedToSession(const User* added_user) {
130 SendSessionInfoIfChanged();
131 SendUserSession(*added_user);
132 }
133
134 // static
135 bool SessionControllerClient::CanLockScreen() {
136 return !UserManager::Get()->GetUnlockUsers().empty();
137 }
138
139 // static
140 bool SessionControllerClient::ShouldLockScreenAutomatically() {
141 // TODO(xiyuan): Observe prefs::kEnableAutoScreenLock and update ash.
142 // Tracked in http://crbug.com/670423
143 const UserList logged_in_users = UserManager::Get()->GetLoggedInUsers();
144 for (auto* user : logged_in_users) {
145 Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(user);
146 if (profile &&
147 profile->GetPrefs()->GetBoolean(prefs::kEnableAutoScreenLock)) {
148 return true;
149 }
150 }
151 return false;
152 }
153
154 // static
155 ash::AddUserSessionPolicy SessionControllerClient::GetAddUserSessionPolicy() {
156 UserManager* const user_manager = UserManager::Get();
157 if (user_manager->GetUsersAllowedForMultiProfile().empty())
158 return ash::AddUserSessionPolicy::ERROR_NO_ELIGIBLE_USERS;
159
160 if (chromeos::MultiProfileUserController::GetPrimaryUserPolicy() !=
161 chromeos::MultiProfileUserController::ALLOWED) {
162 return ash::AddUserSessionPolicy::ERROR_NOT_ALLOWED_PRIMARY_USER;
163 }
164
165 if (UserManager::Get()->GetLoggedInUsers().size() >= kMaxUsers)
166 return ash::AddUserSessionPolicy::ERROR_MAXIMUM_USERS_REACHED;
167
168 return ash::AddUserSessionPolicy::ALLOWED;
169 }
170
171 // static
172 void SessionControllerClient::DoLockScreen() {
173 if (!CanLockScreen())
174 return;
175
176 VLOG(1) << "Requesting screen lock from SessionControllerClient";
177 chromeos::DBusThreadManager::Get()
178 ->GetSessionManagerClient()
179 ->RequestLockScreen();
180 }
181
182 // static
183 void SessionControllerClient::DoSwitchActiveUser(const AccountId& account_id) {
184 // Disallow switching to an already active user since that might crash.
185 // Also check that we got a user id and not an email address.
186 DCHECK_EQ(
187 account_id.GetUserEmail(),
188 gaia::CanonicalizeEmail(gaia::SanitizeEmail(account_id.GetUserEmail())));
189 if (account_id == UserManager::Get()->GetActiveUser()->GetAccountId())
190 return;
191
192 TrySwitchingActiveUser(base::Bind(&DoSwitchUser, account_id));
193 }
194
195 // static
196 void SessionControllerClient::DoCycleActiveUser(bool next_user) {
197 const UserList& logged_in_users = UserManager::Get()->GetLoggedInUsers();
198 if (logged_in_users.size() <= 1)
199 return;
200
201 AccountId account_id = UserManager::Get()->GetActiveUser()->GetAccountId();
202
203 // Get an iterator positioned at the active user.
204 auto it = std::find_if(logged_in_users.begin(), logged_in_users.end(),
205 [account_id](const User* user) {
206 return user->GetAccountId() == account_id;
207 });
208
209 // Active user not found.
210 if (it == logged_in_users.end())
211 return;
212
213 // Get the user's email to select, wrapping to the start/end of the list if
214 // necessary.
215 if (next_user) {
216 if (++it == logged_in_users.end())
217 account_id = (*logged_in_users.begin())->GetAccountId();
218 else
219 account_id = (*it)->GetAccountId();
220 } else {
221 if (it == logged_in_users.begin())
222 it = logged_in_users.end();
223 account_id = (*(--it))->GetAccountId();
224 }
225
226 DoSwitchActiveUser(account_id);
227 }
228
229 void SessionControllerClient::OnSessionStateChanged() {
230 SendSessionInfoIfChanged();
231 }
232
233 void SessionControllerClient::ConnectToSessionControllerAndSetClient() {
234 content::ServiceManagerConnection::GetForProcess()
235 ->GetConnector()
236 ->ConnectToInterface(ash_util::GetAshServiceName(), &session_controller_);
237
238 // Set as |session_controller_|'s client.
239 session_controller_->SetClient(binding_.CreateInterfacePtrAndBind());
240 }
241
242 void SessionControllerClient::SendSessionInfoIfChanged() {
243 ash::mojom::SessionInfoPtr info = ash::mojom::SessionInfo::New();
244 info->max_users = kMaxUsers;
245 info->can_lock_screen = CanLockScreen();
246 info->should_lock_screen_automatically = ShouldLockScreenAutomatically();
247 info->add_user_session_policy = GetAddUserSessionPolicy();
248 info->state = session_manager::SessionManager::Get()->session_state();
249
250 if (info != last_sent_session_info_) {
251 last_sent_session_info_ = info->Clone();
252 session_controller_->SetSessionInfo(std::move(info));
253 }
254 }
255
256 void SessionControllerClient::SendUserSession(const User& user) {
257 session_controller_->UpdateUserSession(UserToUserSession(user));
258 }
259
260 void SessionControllerClient::SendUserSessionOrder() {
261 UserManager* const user_manager = UserManager::Get();
262
263 const UserList logged_in_users = user_manager->GetLoggedInUsers();
264 std::vector<uint32_t> user_session_ids;
265 for (auto* user : user_manager->GetLRULoggedInUsers())
266 user_session_ids.push_back(GetSessionId(user));
267
268 session_controller_->SetUserSessionOrder(user_session_ids);
269 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/ash/session_controller_client.h ('k') | chrome/browser/ui/ash/session_state_delegate_chromeos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698