OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "ash/common/system/user/tray_user.h" | |
6 | |
7 #include "ash/common/session/session_state_delegate.h" | |
8 #include "ash/common/shelf/wm_shelf_util.h" | |
9 #include "ash/common/system/tray/system_tray.h" | |
10 #include "ash/common/system/tray/system_tray_delegate.h" | |
11 #include "ash/common/system/tray/system_tray_notifier.h" | |
12 #include "ash/common/system/tray/tray_constants.h" | |
13 #include "ash/common/system/tray/tray_item_view.h" | |
14 #include "ash/common/system/tray/tray_utils.h" | |
15 #include "ash/common/system/user/rounded_image_view.h" | |
16 #include "ash/common/system/user/user_view.h" | |
17 #include "ash/common/wm_shell.h" | |
18 #include "ash/strings/grit/ash_strings.h" | |
19 #include "base/logging.h" | |
20 #include "base/strings/string16.h" | |
21 #include "components/signin/core/account_id/account_id.h" | |
22 #include "components/user_manager/user_info.h" | |
23 #include "ui/base/l10n/l10n_util.h" | |
24 #include "ui/gfx/image/image.h" | |
25 #include "ui/views/border.h" | |
26 #include "ui/views/controls/label.h" | |
27 #include "ui/views/layout/box_layout.h" | |
28 #include "ui/views/view.h" | |
29 #include "ui/views/widget/widget.h" | |
30 | |
31 namespace { | |
32 | |
33 const int kUserLabelToIconPadding = 5; | |
34 | |
35 } // namespace | |
36 | |
37 namespace ash { | |
38 | |
39 TrayUser::TrayUser(SystemTray* system_tray, UserIndex index) | |
40 : SystemTrayItem(system_tray, UMA_USER), | |
41 user_index_(index), | |
42 user_(nullptr), | |
43 layout_view_(nullptr), | |
44 avatar_(nullptr), | |
45 label_(nullptr) { | |
46 WmShell::Get()->system_tray_notifier()->AddUserObserver(this); | |
47 } | |
48 | |
49 TrayUser::~TrayUser() { | |
50 WmShell::Get()->system_tray_notifier()->RemoveUserObserver(this); | |
51 } | |
52 | |
53 TrayUser::TestState TrayUser::GetStateForTest() const { | |
54 if (!user_) | |
55 return HIDDEN; | |
56 return user_->GetStateForTest(); | |
57 } | |
58 | |
59 gfx::Size TrayUser::GetLayoutSizeForTest() const { | |
60 return layout_view_ ? layout_view_->size() : gfx::Size(); | |
61 } | |
62 | |
63 gfx::Rect TrayUser::GetUserPanelBoundsInScreenForTest() const { | |
64 DCHECK(user_); | |
65 return user_->GetBoundsInScreenOfUserButtonForTest(); | |
66 } | |
67 | |
68 void TrayUser::UpdateAfterLoginStatusChangeForTest(LoginStatus status) { | |
69 UpdateAfterLoginStatusChange(status); | |
70 } | |
71 | |
72 views::View* TrayUser::CreateTrayView(LoginStatus status) { | |
73 CHECK(layout_view_ == nullptr); | |
74 | |
75 layout_view_ = new views::View; | |
76 UpdateAfterLoginStatusChange(status); | |
77 return layout_view_; | |
78 } | |
79 | |
80 views::View* TrayUser::CreateDefaultView(LoginStatus status) { | |
81 if (status == LoginStatus::NOT_LOGGED_IN) | |
82 return nullptr; | |
83 const SessionStateDelegate* session_state_delegate = | |
84 WmShell::Get()->GetSessionStateDelegate(); | |
85 | |
86 // If the screen is locked or a system modal dialog box is shown, show only | |
87 // the currently active user. | |
88 if (user_index_ && (session_state_delegate->IsUserSessionBlocked() || | |
89 WmShell::Get()->IsSystemModalWindowOpen())) | |
90 return nullptr; | |
91 | |
92 CHECK(user_ == nullptr); | |
93 | |
94 int logged_in_users = session_state_delegate->NumberOfLoggedInUsers(); | |
95 | |
96 // Do not show more UserView's then there are logged in users. | |
97 if (user_index_ >= logged_in_users) | |
98 return nullptr; | |
99 | |
100 user_ = new tray::UserView(this, status, user_index_); | |
101 return user_; | |
102 } | |
103 | |
104 void TrayUser::DestroyTrayView() { | |
105 layout_view_ = nullptr; | |
106 avatar_ = nullptr; | |
107 label_ = nullptr; | |
108 } | |
109 | |
110 void TrayUser::DestroyDefaultView() { | |
111 user_ = nullptr; | |
112 } | |
113 | |
114 void TrayUser::UpdateAfterLoginStatusChange(LoginStatus status) { | |
115 // Only the active user is represented in the tray. | |
116 if (!layout_view_) | |
117 return; | |
118 if (user_index_ > 0) | |
119 return; | |
120 bool need_label = false; | |
121 bool need_avatar = false; | |
122 SystemTrayDelegate* delegate = WmShell::Get()->system_tray_delegate(); | |
123 if (delegate->IsUserSupervised()) | |
124 need_label = true; | |
125 switch (status) { | |
126 case LoginStatus::LOCKED: | |
127 case LoginStatus::USER: | |
128 case LoginStatus::OWNER: | |
129 case LoginStatus::PUBLIC: | |
130 need_avatar = true; | |
131 break; | |
132 case LoginStatus::SUPERVISED: | |
133 need_avatar = true; | |
134 need_label = true; | |
135 break; | |
136 case LoginStatus::GUEST: | |
137 need_label = true; | |
138 break; | |
139 case LoginStatus::KIOSK_APP: | |
140 case LoginStatus::ARC_KIOSK_APP: | |
141 case LoginStatus::NOT_LOGGED_IN: | |
142 break; | |
143 } | |
144 | |
145 if ((need_avatar != (avatar_ != nullptr)) || | |
146 (need_label != (label_ != nullptr))) { | |
147 delete label_; | |
148 delete avatar_; | |
149 | |
150 if (need_label) { | |
151 label_ = new views::Label; | |
152 SetupLabelForTray(label_); | |
153 layout_view_->AddChildView(label_); | |
154 } else { | |
155 label_ = nullptr; | |
156 } | |
157 if (need_avatar) { | |
158 avatar_ = new tray::RoundedImageView(kTrayRoundedBorderRadius); | |
159 avatar_->SetPaintToLayer(); | |
160 avatar_->layer()->SetFillsBoundsOpaquely(false); | |
161 layout_view_->AddChildView(avatar_); | |
162 } else { | |
163 avatar_ = nullptr; | |
164 } | |
165 } | |
166 | |
167 if (delegate->IsUserSupervised()) { | |
168 label_->SetText( | |
169 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SUPERVISED_LABEL)); | |
170 } else if (status == LoginStatus::GUEST) { | |
171 label_->SetText(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_GUEST_LABEL)); | |
172 } | |
173 | |
174 UpdateAvatarImage(status); | |
175 | |
176 // Update layout after setting label_ and avatar_ with new login status. | |
177 UpdateLayoutOfItem(); | |
178 } | |
179 | |
180 void TrayUser::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) { | |
181 // Inactive users won't have a layout. | |
182 if (!layout_view_) | |
183 return; | |
184 if (IsHorizontalAlignment(alignment)) { | |
185 if (avatar_) { | |
186 avatar_->SetCornerRadii(0, kTrayRoundedBorderRadius, | |
187 kTrayRoundedBorderRadius, 0); | |
188 } | |
189 if (label_) { | |
190 // If label_ hasn't figured out its size yet, do that first. | |
191 if (label_->GetContentsBounds().height() == 0) | |
192 label_->SizeToPreferredSize(); | |
193 int height = label_->GetContentsBounds().height(); | |
194 int vertical_pad = (kTrayItemSize - height) / 2; | |
195 int remainder = height % 2; | |
196 label_->SetBorder(views::CreateEmptyBorder( | |
197 vertical_pad + remainder, | |
198 kTrayLabelItemHorizontalPaddingBottomAlignment, vertical_pad, | |
199 kTrayLabelItemHorizontalPaddingBottomAlignment)); | |
200 } | |
201 layout_view_->SetLayoutManager(new views::BoxLayout( | |
202 views::BoxLayout::kHorizontal, 0, 0, kUserLabelToIconPadding)); | |
203 } else { | |
204 if (avatar_) { | |
205 avatar_->SetCornerRadii(0, 0, kTrayRoundedBorderRadius, | |
206 kTrayRoundedBorderRadius); | |
207 } | |
208 if (label_) { | |
209 label_->SetBorder(views::CreateEmptyBorder( | |
210 kTrayLabelItemVerticalPaddingVerticalAlignment, | |
211 kTrayLabelItemHorizontalPaddingBottomAlignment, | |
212 kTrayLabelItemVerticalPaddingVerticalAlignment, | |
213 kTrayLabelItemHorizontalPaddingBottomAlignment)); | |
214 } | |
215 layout_view_->SetLayoutManager(new views::BoxLayout( | |
216 views::BoxLayout::kVertical, 0, 0, kUserLabelToIconPadding)); | |
217 } | |
218 } | |
219 | |
220 void TrayUser::OnUserUpdate() { | |
221 UpdateAvatarImage( | |
222 WmShell::Get()->system_tray_delegate()->GetUserLoginStatus()); | |
223 } | |
224 | |
225 void TrayUser::OnUserAddedToSession() { | |
226 SessionStateDelegate* session_state_delegate = | |
227 WmShell::Get()->GetSessionStateDelegate(); | |
228 // Only create views for user items which are logged in. | |
229 if (user_index_ >= session_state_delegate->NumberOfLoggedInUsers()) | |
230 return; | |
231 | |
232 // Enforce a layout change that newly added items become visible. | |
233 UpdateLayoutOfItem(); | |
234 | |
235 // Update the user item. | |
236 UpdateAvatarImage( | |
237 WmShell::Get()->system_tray_delegate()->GetUserLoginStatus()); | |
238 } | |
239 | |
240 void TrayUser::UpdateAvatarImage(LoginStatus status) { | |
241 SessionStateDelegate* session_state_delegate = | |
242 WmShell::Get()->GetSessionStateDelegate(); | |
243 if (!avatar_ || | |
244 user_index_ >= session_state_delegate->NumberOfLoggedInUsers()) | |
245 return; | |
246 | |
247 const user_manager::UserInfo* user_info = | |
248 session_state_delegate->GetUserInfo(user_index_); | |
249 CHECK(user_info); | |
250 avatar_->SetImage(user_info->GetImage(), | |
251 gfx::Size(kTrayItemSize, kTrayItemSize)); | |
252 | |
253 // Unit tests might come here with no images for some users. | |
254 if (avatar_->size().IsEmpty()) | |
255 avatar_->SetSize(gfx::Size(kTrayItemSize, kTrayItemSize)); | |
256 } | |
257 | |
258 void TrayUser::UpdateLayoutOfItem() { | |
259 UpdateAfterShelfAlignmentChange(system_tray()->shelf_alignment()); | |
260 } | |
261 | |
262 } // namespace ash | |
OLD | NEW |