session_controller_impl.cc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  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. #include "ash/session/session_controller_impl.h"
  5. #include <algorithm>
  6. #include <memory>
  7. #include <string>
  8. #include <utility>
  9. #include "ash/metrics/user_metrics_recorder.h"
  10. #include "ash/public/cpp/session/session_activation_observer.h"
  11. #include "ash/public/cpp/session/session_controller_client.h"
  12. #include "ash/public/cpp/session/session_observer.h"
  13. #include "ash/public/cpp/session/user_info.h"
  14. #include "ash/session/fullscreen_controller.h"
  15. #include "ash/session/multiprofiles_intro_dialog.h"
  16. #include "ash/session/session_aborted_dialog.h"
  17. #include "ash/session/teleport_warning_dialog.h"
  18. #include "ash/shell.h"
  19. #include "ash/system/power/power_event_observer.h"
  20. #include "ash/system/screen_security/screen_switch_check_controller.h"
  21. #include "ash/wm/lock_state_controller.h"
  22. #include "ash/wm/mru_window_tracker.h"
  23. #include "ash/wm/window_util.h"
  24. #include "base/auto_reset.h"
  25. #include "base/bind.h"
  26. #include "base/callback_helpers.h"
  27. #include "base/command_line.h"
  28. #include "base/logging.h"
  29. #include "components/account_id/account_id.h"
  30. #include "components/prefs/pref_registry_simple.h"
  31. #include "components/prefs/pref_service.h"
  32. #include "components/user_manager/user_type.h"
  33. #include "ui/message_center/message_center.h"
  34. using session_manager::SessionState;
  35. namespace ash {
  36. SessionControllerImpl::SessionControllerImpl()
  37. : fullscreen_controller_(std::make_unique<FullscreenController>(this)) {}
  38. SessionControllerImpl::~SessionControllerImpl() {
  39. // Abort pending start lock request.
  40. if (!start_lock_callback_.is_null())
  41. std::move(start_lock_callback_).Run(false /* locked */);
  42. }
  43. int SessionControllerImpl::NumberOfLoggedInUsers() const {
  44. return static_cast<int>(user_sessions_.size());
  45. }
  46. AccountId SessionControllerImpl::GetActiveAccountId() const {
  47. return user_sessions_.empty() ? AccountId()
  48. : user_sessions_[0]->user_info.account_id;
  49. }
  50. AddUserSessionPolicy SessionControllerImpl::GetAddUserPolicy() const {
  51. return add_user_session_policy_;
  52. }
  53. bool SessionControllerImpl::IsActiveUserSessionStarted() const {
  54. return !user_sessions_.empty();
  55. }
  56. bool SessionControllerImpl::CanLockScreen() const {
  57. return IsActiveUserSessionStarted() && can_lock_;
  58. }
  59. bool SessionControllerImpl::ShouldLockScreenAutomatically() const {
  60. return should_lock_screen_automatically_;
  61. }
  62. bool SessionControllerImpl::IsRunningInAppMode() const {
  63. return is_running_in_app_mode_;
  64. }
  65. bool SessionControllerImpl::IsDemoSession() const {
  66. return is_demo_session_;
  67. }
  68. bool SessionControllerImpl::IsUserSessionBlocked() const {
  69. // User sessions are blocked when session state is not ACTIVE, with two
  70. // exceptions:
  71. // - LOGGED_IN_NOT_ACTIVE state. This is needed so that browser windows
  72. // created by session restore (or a default new browser window) are properly
  73. // activated before session state changes to ACTIVE.
  74. // - LOCKED state with a running unlocking animation. This is needed because
  75. // the unlocking animation hides the lock container at the end. During the
  76. // unlock animation, IsUserSessionBlocked needs to return unblocked so that
  77. // user windows are deemed activatable and ash correctly restores the active
  78. // window before locking.
  79. return state_ != SessionState::ACTIVE &&
  80. state_ != SessionState::LOGGED_IN_NOT_ACTIVE &&
  81. !(state_ == SessionState::LOCKED && is_unlocking_);
  82. }
  83. bool SessionControllerImpl::IsInSecondaryLoginScreen() const {
  84. return state_ == SessionState::LOGIN_SECONDARY;
  85. }
  86. SessionState SessionControllerImpl::GetSessionState() const {
  87. return state_;
  88. }
  89. bool SessionControllerImpl::ShouldEnableSettings() const {
  90. // Settings opens a web UI window, so it is only available at active session
  91. // at the moment.
  92. return !IsUserSessionBlocked();
  93. }
  94. bool SessionControllerImpl::ShouldShowNotificationTray() const {
  95. if (!IsActiveUserSessionStarted() || IsInSecondaryLoginScreen())
  96. return false;
  97. return true;
  98. }
  99. const SessionControllerImpl::UserSessions&
  100. SessionControllerImpl::GetUserSessions() const {
  101. return user_sessions_;
  102. }
  103. const UserSession* SessionControllerImpl::GetUserSession(
  104. UserIndex index) const {
  105. if (index < 0 || index >= static_cast<UserIndex>(user_sessions_.size()))
  106. return nullptr;
  107. return user_sessions_[index].get();
  108. }
  109. const UserSession* SessionControllerImpl::GetUserSessionByAccountId(
  110. const AccountId& account_id) const {
  111. auto it =
  112. std::find_if(user_sessions_.begin(), user_sessions_.end(),
  113. [&account_id](const std::unique_ptr<UserSession>& session) {
  114. return session->user_info.account_id == account_id;
  115. });
  116. if (it == user_sessions_.end())
  117. return nullptr;
  118. return (*it).get();
  119. }
  120. const UserSession* SessionControllerImpl::GetPrimaryUserSession() const {
  121. auto it = std::find_if(user_sessions_.begin(), user_sessions_.end(),
  122. [this](const std::unique_ptr<UserSession>& session) {
  123. return session->session_id == primary_session_id_;
  124. });
  125. if (it == user_sessions_.end())
  126. return nullptr;
  127. return (*it).get();
  128. }
  129. bool SessionControllerImpl::IsUserChild() const {
  130. if (!IsActiveUserSessionStarted())
  131. return false;
  132. user_manager::UserType active_user_type = GetUserSession(0)->user_info.type;
  133. return active_user_type == user_manager::USER_TYPE_CHILD;
  134. }
  135. bool SessionControllerImpl::IsUserPublicAccount() const {
  136. if (!IsActiveUserSessionStarted())
  137. return false;
  138. user_manager::UserType active_user_type = GetUserSession(0)->user_info.type;
  139. return active_user_type == user_manager::USER_TYPE_PUBLIC_ACCOUNT;
  140. }
  141. absl::optional<user_manager::UserType> SessionControllerImpl::GetUserType()
  142. const {
  143. if (!IsActiveUserSessionStarted())
  144. return absl::nullopt;
  145. return absl::make_optional(GetUserSession(0)->user_info.type);
  146. }
  147. bool SessionControllerImpl::IsUserPrimary() const {
  148. if (!IsActiveUserSessionStarted())
  149. return false;
  150. return GetUserSession(0)->session_id == primary_session_id_;
  151. }
  152. bool SessionControllerImpl::IsUserFirstLogin() const {
  153. if (!IsActiveUserSessionStarted())
  154. return false;
  155. return GetUserSession(0)->user_info.is_new_profile;
  156. }
  157. bool SessionControllerImpl::IsEnterpriseManaged() const {
  158. return client_ && client_->IsEnterpriseManaged();
  159. }
  160. bool SessionControllerImpl::ShouldDisplayManagedUI() const {
  161. if (!IsActiveUserSessionStarted())
  162. return false;
  163. return GetUserSession(0)->user_info.should_display_managed_ui;
  164. }
  165. void SessionControllerImpl::LockScreen() {
  166. if (client_)
  167. client_->RequestLockScreen();
  168. }
  169. void SessionControllerImpl::HideLockScreen() {
  170. if (client_)
  171. client_->RequestHideLockScreen();
  172. }
  173. void SessionControllerImpl::RequestSignOut() {
  174. if (client_)
  175. client_->RequestSignOut();
  176. }
  177. void SessionControllerImpl::AttemptRestartChrome() {
  178. if (client_)
  179. client_->AttemptRestartChrome();
  180. }
  181. void SessionControllerImpl::SwitchActiveUser(const AccountId& account_id) {
  182. if (client_)
  183. client_->SwitchActiveUser(account_id);
  184. }
  185. void SessionControllerImpl::CycleActiveUser(CycleUserDirection direction) {
  186. if (client_)
  187. client_->CycleActiveUser(direction);
  188. }
  189. void SessionControllerImpl::ShowMultiProfileLogin() {
  190. if (client_)
  191. client_->ShowMultiProfileLogin();
  192. }
  193. PrefService* SessionControllerImpl::GetSigninScreenPrefService() const {
  194. return client_ ? client_->GetSigninScreenPrefService() : nullptr;
  195. }
  196. PrefService* SessionControllerImpl::GetUserPrefServiceForUser(
  197. const AccountId& account_id) const {
  198. return client_ ? client_->GetUserPrefService(account_id) : nullptr;
  199. }
  200. PrefService* SessionControllerImpl::GetPrimaryUserPrefService() const {
  201. const UserSession* session = GetPrimaryUserSession();
  202. return session ? GetUserPrefServiceForUser(session->user_info.account_id)
  203. : nullptr;
  204. }
  205. PrefService* SessionControllerImpl::GetLastActiveUserPrefService() const {
  206. return last_active_user_prefs_;
  207. }
  208. PrefService* SessionControllerImpl::GetActivePrefService() const {
  209. // Use the active user prefs once they become available. Check the PrefService
  210. // object instead of session state because prefs load is async after login.
  211. if (last_active_user_prefs_)
  212. return last_active_user_prefs_;
  213. return GetSigninScreenPrefService();
  214. }
  215. void SessionControllerImpl::AddObserver(SessionObserver* observer) {
  216. observers_.AddObserver(observer);
  217. }
  218. void SessionControllerImpl::RemoveObserver(SessionObserver* observer) {
  219. observers_.RemoveObserver(observer);
  220. }
  221. bool SessionControllerImpl::IsScreenLocked() const {
  222. return state_ == SessionState::LOCKED;
  223. }
  224. void SessionControllerImpl::SetClient(SessionControllerClient* client) {
  225. client_ = client;
  226. }
  227. void SessionControllerImpl::SetSessionInfo(const SessionInfo& info) {
  228. can_lock_ = info.can_lock_screen;
  229. should_lock_screen_automatically_ = info.should_lock_screen_automatically;
  230. is_running_in_app_mode_ = info.is_running_in_app_mode;
  231. if (info.is_demo_session)
  232. SetIsDemoSession();
  233. add_user_session_policy_ = info.add_user_session_policy;
  234. SetSessionState(info.state);
  235. }
  236. void SessionControllerImpl::UpdateUserSession(const UserSession& user_session) {
  237. auto it = std::find_if(
  238. user_sessions_.begin(), user_sessions_.end(),
  239. [&user_session](const std::unique_ptr<UserSession>& session) {
  240. return session->session_id == user_session.session_id;
  241. });
  242. if (it == user_sessions_.end()) {
  243. AddUserSession(user_session);
  244. return;
  245. }
  246. *it = std::make_unique<UserSession>(user_session);
  247. for (auto& observer : observers_)
  248. observer.OnUserSessionUpdated((*it)->user_info.account_id);
  249. UpdateLoginStatus();
  250. }
  251. void SessionControllerImpl::SetUserSessionOrder(
  252. const std::vector<uint32_t>& user_session_order) {
  253. DCHECK_EQ(user_sessions_.size(), user_session_order.size());
  254. AccountId last_active_account_id;
  255. if (user_sessions_.size())
  256. last_active_account_id = user_sessions_[0]->user_info.account_id;
  257. // Adjusts |user_sessions_| to match the given order.
  258. std::vector<std::unique_ptr<UserSession>> sessions;
  259. for (const auto& session_id : user_session_order) {
  260. auto it =
  261. std::find_if(user_sessions_.begin(), user_sessions_.end(),
  262. [session_id](const std::unique_ptr<UserSession>& session) {
  263. return session && session->session_id == session_id;
  264. });
  265. if (it == user_sessions_.end()) {
  266. LOG(ERROR) << "Unknown session id =" << session_id;
  267. continue;
  268. }
  269. sessions.push_back(std::move(*it));
  270. }
  271. user_sessions_.swap(sessions);
  272. // Check active user change and notifies observers.
  273. if (user_sessions_[0]->session_id != active_session_id_) {
  274. const bool is_first_session = active_session_id_ == 0u;
  275. active_session_id_ = user_sessions_[0]->session_id;
  276. if (is_first_session) {
  277. for (auto& observer : observers_)
  278. observer.OnFirstSessionStarted();
  279. }
  280. session_activation_observer_holder_.NotifyActiveSessionChanged(
  281. last_active_account_id, user_sessions_[0]->user_info.account_id);
  282. // When switching to a user for whose PrefService is not ready,
  283. // |last_active_user_prefs_| continues to point to the PrefService of the
  284. // most-recently active user with a loaded PrefService.
  285. PrefService* user_pref_service =
  286. GetUserPrefServiceForUser(user_sessions_[0]->user_info.account_id);
  287. if (user_pref_service && last_active_user_prefs_ != user_pref_service) {
  288. last_active_user_prefs_ = user_pref_service;
  289. MaybeNotifyOnActiveUserPrefServiceChanged();
  290. }
  291. for (auto& observer : observers_) {
  292. observer.OnActiveUserSessionChanged(
  293. user_sessions_[0]->user_info.account_id);
  294. }
  295. UpdateLoginStatus();
  296. }
  297. }
  298. void SessionControllerImpl::PrepareForLock(PrepareForLockCallback callback) {
  299. fullscreen_controller_->MaybeExitFullscreenBeforeLock(std::move(callback));
  300. }
  301. void SessionControllerImpl::StartLock(StartLockCallback callback) {
  302. DCHECK(start_lock_callback_.is_null());
  303. start_lock_callback_ = std::move(callback);
  304. LockStateController* const lock_state_controller =
  305. Shell::Get()->lock_state_controller();
  306. lock_state_controller->SetLockScreenDisplayedCallback(
  307. base::BindOnce(&SessionControllerImpl::OnLockAnimationFinished,
  308. weak_ptr_factory_.GetWeakPtr()));
  309. }
  310. void SessionControllerImpl::NotifyChromeLockAnimationsComplete() {
  311. Shell::Get()->power_event_observer()->OnLockAnimationsComplete();
  312. }
  313. void SessionControllerImpl::RunUnlockAnimation(
  314. RunUnlockAnimationCallback callback) {
  315. is_unlocking_ = true;
  316. // Shell could have no instance in tests.
  317. if (Shell::HasInstance())
  318. Shell::Get()->lock_state_controller()->OnLockScreenHide(
  319. std::move(callback));
  320. }
  321. void SessionControllerImpl::NotifyChromeTerminating() {
  322. for (auto& observer : observers_)
  323. observer.OnChromeTerminating();
  324. }
  325. void SessionControllerImpl::SetSessionLengthLimit(base::TimeDelta length_limit,
  326. base::Time start_time) {
  327. session_length_limit_ = length_limit;
  328. session_start_time_ = start_time;
  329. for (auto& observer : observers_)
  330. observer.OnSessionLengthLimitChanged();
  331. }
  332. void SessionControllerImpl::CanSwitchActiveUser(
  333. CanSwitchActiveUserCallback callback) {
  334. Shell::Get()->screen_switch_check_controller()->CanSwitchAwayFromActiveUser(
  335. std::move(callback));
  336. }
  337. void SessionControllerImpl::ShowMultiprofilesIntroDialog(
  338. ShowMultiprofilesIntroDialogCallback callback) {
  339. MultiprofilesIntroDialog::Show(std::move(callback));
  340. }
  341. void SessionControllerImpl::ShowTeleportWarningDialog(
  342. ShowTeleportWarningDialogCallback callback) {
  343. TeleportWarningDialog::Show(std::move(callback));
  344. }
  345. void SessionControllerImpl::ShowMultiprofilesSessionAbortedDialog(
  346. const std::string& user_email) {
  347. SessionAbortedDialog::Show(user_email);
  348. }
  349. void SessionControllerImpl::AddSessionActivationObserverForAccountId(
  350. const AccountId& account_id,
  351. SessionActivationObserver* observer) {
  352. bool locked = state_ == SessionState::LOCKED;
  353. observer->OnLockStateChanged(locked);
  354. observer->OnSessionActivated(user_sessions_.size() &&
  355. user_sessions_[0]->user_info.account_id ==
  356. account_id);
  357. session_activation_observer_holder_.AddForAccountId(account_id, observer);
  358. }
  359. void SessionControllerImpl::RemoveSessionActivationObserverForAccountId(
  360. const AccountId& account_id,
  361. SessionActivationObserver* observer) {
  362. session_activation_observer_holder_.RemoveForAccountId(account_id, observer);
  363. }
  364. void SessionControllerImpl::ClearUserSessionsForTest() {
  365. user_sessions_.clear();
  366. last_active_user_prefs_ = nullptr;
  367. active_session_id_ = 0u;
  368. primary_session_id_ = 0u;
  369. }
  370. void SessionControllerImpl::SetIsDemoSession() {
  371. if (is_demo_session_)
  372. return;
  373. is_demo_session_ = true;
  374. Shell::Get()->metrics()->StartDemoSessionMetricsRecording();
  375. // Notifications should be silenced during demo sessions.
  376. message_center::MessageCenter::Get()->SetQuietMode(true);
  377. }
  378. void SessionControllerImpl::SetSessionState(SessionState state) {
  379. if (state_ == state)
  380. return;
  381. base::AutoReset<bool> in_progress(&session_state_change_in_progress_, true);
  382. const bool was_user_session_blocked = IsUserSessionBlocked();
  383. const bool was_locked = state_ == SessionState::LOCKED;
  384. state_ = state;
  385. for (auto& observer : observers_)
  386. observer.OnSessionStateChanged(state_);
  387. UpdateLoginStatus();
  388. const bool locked = state_ == SessionState::LOCKED;
  389. if (was_locked != locked) {
  390. if (!locked)
  391. is_unlocking_ = false;
  392. for (auto& observer : observers_)
  393. observer.OnLockStateChanged(locked);
  394. session_activation_observer_holder_.NotifyLockStateChanged(locked);
  395. }
  396. EnsureSigninScreenPrefService();
  397. if (was_user_session_blocked && !IsUserSessionBlocked())
  398. EnsureActiveWindowAfterUnblockingUserSession();
  399. }
  400. void SessionControllerImpl::AddUserSession(const UserSession& user_session) {
  401. if (primary_session_id_ == 0u)
  402. primary_session_id_ = user_session.session_id;
  403. user_sessions_.push_back(std::make_unique<UserSession>(user_session));
  404. const AccountId account_id(user_session.user_info.account_id);
  405. PrefService* user_prefs = GetUserPrefServiceForUser(account_id);
  406. // |user_prefs| could be null in tests.
  407. if (user_prefs)
  408. OnProfilePrefServiceInitialized(account_id, user_prefs);
  409. UpdateLoginStatus();
  410. for (auto& observer : observers_)
  411. observer.OnUserSessionAdded(account_id);
  412. }
  413. LoginStatus SessionControllerImpl::CalculateLoginStatus() const {
  414. // TODO(jamescook|xiyuan): There is not a 1:1 mapping of SessionState to
  415. // LoginStatus. Fix the cases that don't match. http://crbug.com/701193
  416. switch (state_) {
  417. case SessionState::UNKNOWN:
  418. case SessionState::OOBE:
  419. case SessionState::LOGIN_PRIMARY:
  420. case SessionState::LOGGED_IN_NOT_ACTIVE:
  421. case SessionState::RMA:
  422. return LoginStatus::NOT_LOGGED_IN;
  423. case SessionState::ACTIVE:
  424. return CalculateLoginStatusForActiveSession();
  425. case SessionState::LOCKED:
  426. return LoginStatus::LOCKED;
  427. case SessionState::LOGIN_SECONDARY:
  428. // TODO(jamescook): There is no LoginStatus for this.
  429. return LoginStatus::USER;
  430. }
  431. NOTREACHED();
  432. return LoginStatus::NOT_LOGGED_IN;
  433. }
  434. LoginStatus SessionControllerImpl::CalculateLoginStatusForActiveSession()
  435. const {
  436. DCHECK(state_ == SessionState::ACTIVE);
  437. if (user_sessions_.empty()) // Can be empty in tests.
  438. return LoginStatus::USER;
  439. switch (user_sessions_[0]->user_info.type) {
  440. case user_manager::USER_TYPE_REGULAR:
  441. return LoginStatus::USER;
  442. case user_manager::USER_TYPE_GUEST:
  443. return LoginStatus::GUEST;
  444. case user_manager::USER_TYPE_PUBLIC_ACCOUNT:
  445. return LoginStatus::PUBLIC;
  446. case user_manager::USER_TYPE_KIOSK_APP:
  447. return LoginStatus::KIOSK_APP;
  448. case user_manager::USER_TYPE_CHILD:
  449. return LoginStatus::CHILD;
  450. case user_manager::USER_TYPE_ARC_KIOSK_APP:
  451. return LoginStatus::KIOSK_APP;
  452. case user_manager::USER_TYPE_ACTIVE_DIRECTORY:
  453. // TODO(jamescook): There is no LoginStatus for this.
  454. return LoginStatus::USER;
  455. case user_manager::USER_TYPE_WEB_KIOSK_APP:
  456. return LoginStatus::KIOSK_APP;
  457. case user_manager::NUM_USER_TYPES:
  458. // Avoid having a "default" case so the compiler catches new enum values.
  459. NOTREACHED();
  460. return LoginStatus::USER;
  461. }
  462. NOTREACHED();
  463. return LoginStatus::USER;
  464. }
  465. void SessionControllerImpl::UpdateLoginStatus() {
  466. const LoginStatus new_login_status = CalculateLoginStatus();
  467. if (new_login_status == login_status_)
  468. return;
  469. login_status_ = new_login_status;
  470. for (auto& observer : observers_)
  471. observer.OnLoginStatusChanged(login_status_);
  472. }
  473. void SessionControllerImpl::OnLockAnimationFinished() {
  474. if (!start_lock_callback_.is_null())
  475. std::move(start_lock_callback_).Run(true /* locked */);
  476. }
  477. void SessionControllerImpl::EnsureSigninScreenPrefService() {
  478. // Obtain and notify signin profile prefs only once.
  479. if (signin_screen_prefs_obtained_)
  480. return;
  481. PrefService* const signin_prefs = GetSigninScreenPrefService();
  482. if (!signin_prefs)
  483. return;
  484. OnSigninScreenPrefServiceInitialized(signin_prefs);
  485. }
  486. void SessionControllerImpl::OnSigninScreenPrefServiceInitialized(
  487. PrefService* pref_service) {
  488. DCHECK(pref_service);
  489. DCHECK(!signin_screen_prefs_obtained_);
  490. signin_screen_prefs_obtained_ = true;
  491. for (auto& observer : observers_)
  492. observer.OnSigninScreenPrefServiceInitialized(pref_service);
  493. if (on_active_user_prefs_changed_notify_deferred_) {
  494. // Notify obsevers with the deferred OnActiveUserPrefServiceChanged(). Do
  495. // this in a separate loop from the above since observers might depend on
  496. // each other and we want to avoid having inconsistent states.
  497. for (auto& observer : observers_)
  498. observer.OnActiveUserPrefServiceChanged(last_active_user_prefs_);
  499. on_active_user_prefs_changed_notify_deferred_ = false;
  500. }
  501. }
  502. void SessionControllerImpl::OnProfilePrefServiceInitialized(
  503. const AccountId& account_id,
  504. PrefService* pref_service) {
  505. // |pref_service| can be null in tests.
  506. if (!pref_service)
  507. return;
  508. DCHECK(!user_sessions_.empty());
  509. if (account_id == user_sessions_[0]->user_info.account_id) {
  510. last_active_user_prefs_ = pref_service;
  511. MaybeNotifyOnActiveUserPrefServiceChanged();
  512. }
  513. }
  514. void SessionControllerImpl::MaybeNotifyOnActiveUserPrefServiceChanged() {
  515. DCHECK(last_active_user_prefs_);
  516. if (!signin_screen_prefs_obtained_) {
  517. // We must guarantee that OnSigninScreenPrefServiceInitialized() is called
  518. // before OnActiveUserPrefServiceChanged(), so defer notifying the
  519. // observers until the sign in prefs are received.
  520. on_active_user_prefs_changed_notify_deferred_ = true;
  521. return;
  522. }
  523. for (auto& observer : observers_)
  524. observer.OnActiveUserPrefServiceChanged(last_active_user_prefs_);
  525. }
  526. void SessionControllerImpl::EnsureActiveWindowAfterUnblockingUserSession() {
  527. // This happens only in tests (See SessionControllerImplTest).
  528. if (!Shell::HasInstance())
  529. return;
  530. auto mru_list =
  531. Shell::Get()->mru_window_tracker()->BuildMruWindowList(kActiveDesk);
  532. if (!mru_list.empty())
  533. mru_list.front()->Focus();
  534. }
  535. } // namespace ash