| 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 |