blob: af96c81a43df592d42bf456bb9358e19308f8de6 [file] [log] [blame]
James Cookb0bf8e82017-04-09 17:01:441// 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 "ash/shelf/shelf_controller.h"
6
Mitsuru Oshima04b54d02017-10-09 14:22:457#include <memory>
8
Michael Wasserman39e4fe42017-08-08 23:49:429#include "ash/public/cpp/ash_pref_names.h"
msw19b30c2c2017-06-01 03:21:4010#include "ash/public/cpp/remote_shelf_item_delegate.h"
Michael Wasserman39e4fe42017-08-08 23:49:4211#include "ash/public/cpp/shelf_prefs.h"
James Cookb0bf8e82017-04-09 17:01:4412#include "ash/root_window_controller.h"
jamescook788b4fc2017-05-18 16:16:0613#include "ash/session/session_controller.h"
James Cookb0bf8e82017-04-09 17:01:4414#include "ash/shelf/app_list_shelf_item_delegate.h"
James Cook840177e2017-05-25 02:20:0115#include "ash/shelf/shelf.h"
Alex Newcomera3bcc9b2018-03-02 18:06:0816#include "ash/shelf/shelf_constants.h"
Sammie Quon8f7d4c12018-08-08 18:27:4617#include "ash/shelf/shelf_widget.h"
James Cookb0bf8e82017-04-09 17:01:4418#include "ash/shell.h"
msw109806d2017-06-02 20:11:5719#include "ash/strings/grit/ash_strings.h"
Xiyuan Xia474c66c2018-05-18 05:11:2220#include "ash/system/message_center/arc/arc_notification_constants.h"
Qiang Xub7127da62017-08-29 01:44:5721#include "ash/wm/tablet_mode/tablet_mode_controller.h"
msw19b30c2c2017-06-01 03:21:4022#include "base/auto_reset.h"
Evan Stade0f41a342018-09-14 22:15:5023#include "chromeos/strings/grit/chromeos_strings.h"
Michael Wasserman39e4fe42017-08-08 23:49:4224#include "components/pref_registry/pref_registry_syncable.h"
25#include "components/prefs/pref_change_registrar.h"
26#include "components/prefs/pref_registry_simple.h"
27#include "components/prefs/pref_service.h"
msw109806d2017-06-02 20:11:5728#include "ui/base/l10n/l10n_util.h"
James Cookb0bf8e82017-04-09 17:01:4429#include "ui/base/models/simple_menu_model.h"
Alex Newcomer509bf672018-02-08 00:03:3030#include "ui/base/ui_base_features.h"
James Cookb0bf8e82017-04-09 17:01:4431#include "ui/display/display.h"
32#include "ui/display/screen.h"
Alex Newcomerd929ca162018-01-18 23:24:4733#include "ui/message_center/message_center.h"
James Cookb0bf8e82017-04-09 17:01:4434
35namespace ash {
36
37namespace {
38
James Cook840177e2017-05-25 02:20:0139// Returns the Shelf instance for the display with the given |display_id|.
40Shelf* GetShelfForDisplay(int64_t display_id) {
James Cookb0bf8e82017-04-09 17:01:4441 // The controller may be null for invalid ids or for displays being removed.
42 RootWindowController* root_window_controller =
43 Shell::GetRootWindowControllerWithDisplayId(display_id);
jamescookaa9f49f2017-05-30 20:48:4544 return root_window_controller ? root_window_controller->shelf() : nullptr;
James Cookb0bf8e82017-04-09 17:01:4445}
46
Michael Wasserman39e4fe42017-08-08 23:49:4247// Set each Shelf's auto-hide behavior from the per-display pref.
48void SetShelfAutoHideFromPrefs() {
49 // TODO(jamescook): The session state check should not be necessary, but
50 // otherwise this wrongly tries to set the alignment on a secondary display
51 // during login before the ShelfLockingManager is created.
52 SessionController* session_controller = Shell::Get()->session_controller();
Sam McNallyf4dab612017-08-16 03:06:3353 PrefService* prefs = session_controller->GetLastActiveUserPrefService();
Michael Wasserman39e4fe42017-08-08 23:49:4254 if (!prefs || !session_controller->IsActiveUserSessionStarted())
55 return;
56
57 for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
58 auto value = GetShelfAutoHideBehaviorPref(prefs, display.id());
59 // Don't show the shelf in app mode.
60 if (session_controller->IsRunningInAppMode())
61 value = SHELF_AUTO_HIDE_ALWAYS_HIDDEN;
62 Shelf* shelf = GetShelfForDisplay(display.id());
63 if (shelf)
64 shelf->SetAutoHideBehavior(value);
65 }
66}
67
68// Set each Shelf's alignment from the per-display pref.
69void SetShelfAlignmentFromPrefs() {
70 // TODO(jamescook): The session state check should not be necessary, but
71 // otherwise this wrongly tries to set the alignment on a secondary display
72 // during login before the ShelfLockingManager is created.
73 SessionController* session_controller = Shell::Get()->session_controller();
Sam McNallyf4dab612017-08-16 03:06:3374 PrefService* prefs = session_controller->GetLastActiveUserPrefService();
Michael Wasserman39e4fe42017-08-08 23:49:4275 if (!prefs || !session_controller->IsActiveUserSessionStarted())
76 return;
77
78 for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
79 auto value = GetShelfAlignmentPref(prefs, display.id());
80 Shelf* shelf = GetShelfForDisplay(display.id());
81 if (shelf)
82 shelf->SetAlignment(value);
83 }
84}
85
Aga Wronska8af5e102018-05-18 16:45:0386void UpdateShelfVisibility() {
87 for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
88 Shelf* shelf = GetShelfForDisplay(display.id());
89 if (shelf)
90 shelf->UpdateVisibilityState();
91 }
92}
93
Michael Wasserman39e4fe42017-08-08 23:49:4294// Set each Shelf's auto-hide behavior and alignment from the per-display prefs.
95void SetShelfBehaviorsFromPrefs() {
Vladislav Kaznacheev0632cd62018-08-30 21:37:1596 SetShelfAutoHideFromPrefs();
97
98 // The shelf should always be bottom-aligned in tablet mode; alignment is
99 // assigned from prefs when tablet mode is exited.
James Cookd2495fe2018-03-19 19:53:10100 if (Shell::Get()
101 ->tablet_mode_controller()
102 ->IsTabletModeWindowManagerEnabled()) {
Sammie Quona9c65a42017-11-29 21:18:42103 return;
104 }
105
Michael Wasserman39e4fe42017-08-08 23:49:42106 SetShelfAlignmentFromPrefs();
107}
108
James Cookb0bf8e82017-04-09 17:01:44109} // namespace
110
Alex Newcomerd929ca162018-01-18 23:24:47111ShelfController::ShelfController()
Alex Newcomerd7b0cc42018-05-25 22:58:48112 : is_notification_indicator_enabled_(
113 features::IsNotificationIndicatorEnabled()),
Alex Newcomerd929ca162018-01-18 23:24:47114 message_center_observer_(this) {
Sammie Quon9b911f2f2017-12-15 02:53:15115 // Set the delegate and title string for the back button.
116 model_.SetShelfItemDelegate(ShelfID(kBackButtonId), nullptr);
117 DCHECK_EQ(0, model_.ItemIndexByID(ShelfID(kBackButtonId)));
118 ShelfItem back_item = model_.items()[0];
119 back_item.title = l10n_util::GetStringUTF16(IDS_ASH_SHELF_BACK_BUTTON_TITLE);
120 model_.Set(0, back_item);
121
msw109806d2017-06-02 20:11:57122 // Set the delegate and title string for the app list item.
msw19b30c2c2017-06-01 03:21:40123 model_.SetShelfItemDelegate(ShelfID(kAppListId),
Mitsuru Oshima04b54d02017-10-09 14:22:45124 std::make_unique<AppListShelfItemDelegate>());
Sammie Quon9b911f2f2017-12-15 02:53:15125 DCHECK_EQ(1, model_.ItemIndexByID(ShelfID(kAppListId)));
126 ShelfItem launcher_item = model_.items()[1];
127 launcher_item.title =
128 l10n_util::GetStringUTF16(IDS_ASH_SHELF_APP_LIST_LAUNCHER_TITLE);
129 model_.Set(1, launcher_item);
msw109806d2017-06-02 20:11:57130
msw19b30c2c2017-06-01 03:21:40131 model_.AddObserver(this);
Sam McNallyf4dab612017-08-16 03:06:33132 Shell::Get()->session_controller()->AddObserver(this);
Qiang Xub7127da62017-08-29 01:44:57133 Shell::Get()->tablet_mode_controller()->AddObserver(this);
Michael Wasserman39e4fe42017-08-08 23:49:42134 Shell::Get()->window_tree_host_manager()->AddObserver(this);
Alex Newcomerd7b0cc42018-05-25 22:58:48135 if (is_notification_indicator_enabled_)
Alex Newcomerd929ca162018-01-18 23:24:47136 message_center_observer_.Add(message_center::MessageCenter::Get());
James Cookb0bf8e82017-04-09 17:01:44137}
138
msw19b30c2c2017-06-01 03:21:40139ShelfController::~ShelfController() {
140 model_.RemoveObserver(this);
Mike Wasserman4cc9f402017-09-18 20:59:27141 model_.DestroyItemDelegates();
msw19b30c2c2017-06-01 03:21:40142}
James Cookb0bf8e82017-04-09 17:01:44143
James Cookd2495fe2018-03-19 19:53:10144void ShelfController::Shutdown() {
145 Shell::Get()->window_tree_host_manager()->RemoveObserver(this);
146 Shell::Get()->tablet_mode_controller()->RemoveObserver(this);
147 Shell::Get()->session_controller()->RemoveObserver(this);
148}
149
Michael Wasserman39e4fe42017-08-08 23:49:42150// static
151void ShelfController::RegisterProfilePrefs(PrefRegistrySimple* registry) {
James Cook5bd29692018-03-28 14:31:51152 // These prefs are public for ChromeLauncherController's OnIsSyncingChanged.
153 // See the pref names definitions for explanations of the synced, local, and
154 // per-display behaviors.
Michael Wasserman39e4fe42017-08-08 23:49:42155 registry->RegisterStringPref(
156 prefs::kShelfAutoHideBehavior, kShelfAutoHideBehaviorNever,
157 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
158 registry->RegisterStringPref(prefs::kShelfAutoHideBehaviorLocal,
159 std::string(), PrefRegistry::PUBLIC);
160 registry->RegisterStringPref(
161 prefs::kShelfAlignment, kShelfAlignmentBottom,
162 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
163 registry->RegisterStringPref(prefs::kShelfAlignmentLocal, std::string(),
164 PrefRegistry::PUBLIC);
165 registry->RegisterDictionaryPref(prefs::kShelfPreferences,
166 PrefRegistry::PUBLIC);
167}
168
James Cookb0bf8e82017-04-09 17:01:44169void ShelfController::BindRequest(mojom::ShelfControllerRequest request) {
170 bindings_.AddBinding(this, std::move(request));
171}
172
James Cookb0bf8e82017-04-09 17:01:44173void ShelfController::AddObserver(
174 mojom::ShelfObserverAssociatedPtrInfo observer) {
175 mojom::ShelfObserverAssociatedPtr observer_ptr;
176 observer_ptr.Bind(std::move(observer));
msw19b30c2c2017-06-01 03:21:40177
Mike Wasserman5909b562018-02-20 18:00:46178 // Synchronize two ShelfModel instances, one each owned by Ash and Chrome.
179 // Notify Chrome of existing ShelfModel items and delegates created by Ash.
180 for (int i = 0; i < model_.item_count(); ++i) {
181 ShelfItem item = model_.items()[i];
182 ShelfItemDelegate* delegate = model_.GetShelfItemDelegate(item.id);
183 // Notify observers of the delegate before the items themselves; Chrome
184 // creates default delegates if none exist, breaking ShelfWindowWatcher.
185 if (delegate) {
186 observer_ptr->OnShelfItemDelegateChanged(
187 item.id, delegate->CreateInterfacePtrAndBind());
msw19b30c2c2017-06-01 03:21:40188 }
Mike Wasserman5909b562018-02-20 18:00:46189 // Pass null images to avoid transport costs; clients don't use images.
190 item.image = gfx::ImageSkia();
191 observer_ptr->OnShelfItemAdded(i, item);
msw19b30c2c2017-06-01 03:21:40192 }
193
James Cookb0bf8e82017-04-09 17:01:44194 observers_.AddPtr(std::move(observer_ptr));
195}
196
msw19b30c2c2017-06-01 03:21:40197void ShelfController::AddShelfItem(int32_t index, const ShelfItem& item) {
msw70ac45f2017-06-05 02:02:45198 DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
msw19b30c2c2017-06-01 03:21:40199 index = index < 0 ? model_.item_count() : index;
Julien Brianceau293917a82017-08-01 17:32:59200 DCHECK_GT(index, 0) << " Items can not precede the AppList";
msw70ac45f2017-06-05 02:02:45201 DCHECK_LE(index, model_.item_count()) << " Index out of bounds";
msw19b30c2c2017-06-01 03:21:40202 index = std::min(std::max(index, 1), model_.item_count());
203 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
204 model_.AddAt(index, item);
James Cookb0bf8e82017-04-09 17:01:44205}
206
msw19b30c2c2017-06-01 03:21:40207void ShelfController::RemoveShelfItem(const ShelfID& id) {
msw70ac45f2017-06-05 02:02:45208 DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
msw19b30c2c2017-06-01 03:21:40209 const int index = model_.ItemIndexByID(id);
msw70ac45f2017-06-05 02:02:45210 DCHECK_GE(index, 0) << " No item found with the id: " << id;
211 DCHECK_NE(index, 0) << " The AppList shelf item cannot be removed";
msw19b30c2c2017-06-01 03:21:40212 if (index <= 0)
213 return;
214 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
215 model_.RemoveItemAt(index);
James Cookb0bf8e82017-04-09 17:01:44216}
217
msw19b30c2c2017-06-01 03:21:40218void ShelfController::MoveShelfItem(const ShelfID& id, int32_t index) {
msw70ac45f2017-06-05 02:02:45219 DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
msw19b30c2c2017-06-01 03:21:40220 const int current_index = model_.ItemIndexByID(id);
msw70ac45f2017-06-05 02:02:45221 DCHECK_GE(current_index, 0) << " No item found with the id: " << id;
222 DCHECK_NE(current_index, 0) << " The AppList shelf item cannot be moved";
msw19b30c2c2017-06-01 03:21:40223 if (current_index <= 0)
224 return;
Julien Brianceau293917a82017-08-01 17:32:59225 DCHECK_GT(index, 0) << " Items can not precede the AppList";
msw70ac45f2017-06-05 02:02:45226 DCHECK_LT(index, model_.item_count()) << " Index out of bounds";
msw19b30c2c2017-06-01 03:21:40227 index = std::min(std::max(index, 1), model_.item_count() - 1);
Mike Wassermanf0145092017-09-29 01:30:54228 if (current_index == index) {
229 DVLOG(1) << "The item is already at the given index (" << index << "). "
230 << "This happens when syncing a ShelfModel weight reordering.";
msw19b30c2c2017-06-01 03:21:40231 return;
Mike Wassermanf0145092017-09-29 01:30:54232 }
msw19b30c2c2017-06-01 03:21:40233 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
234 model_.Move(current_index, index);
235}
236
237void ShelfController::UpdateShelfItem(const ShelfItem& item) {
msw70ac45f2017-06-05 02:02:45238 DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
msw19b30c2c2017-06-01 03:21:40239 const int index = model_.ItemIndexByID(item.id);
msw70ac45f2017-06-05 02:02:45240 DCHECK_GE(index, 0) << " No item found with the id: " << item.id;
msw19b30c2c2017-06-01 03:21:40241 if (index < 0)
242 return;
243 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
Mike Wassermanb4ed7eab2017-10-10 07:08:25244
245 // Keep any existing image if the item was sent without one for efficiency.
Xiyuan Xia474c66c2018-05-18 05:11:22246 ShelfItem new_item = item;
Mike Wassermanb4ed7eab2017-10-10 07:08:25247 if (item.image.isNull())
248 new_item.image = model_.items()[index].image;
249 model_.Set(index, new_item);
msw19b30c2c2017-06-01 03:21:40250}
251
252void ShelfController::SetShelfItemDelegate(
253 const ShelfID& id,
254 mojom::ShelfItemDelegatePtr delegate) {
msw70ac45f2017-06-05 02:02:45255 DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
msw19b30c2c2017-06-01 03:21:40256 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
257 if (delegate.is_bound())
258 model_.SetShelfItemDelegate(
Mitsuru Oshima04b54d02017-10-09 14:22:45259 id, std::make_unique<RemoteShelfItemDelegate>(id, std::move(delegate)));
msw19b30c2c2017-06-01 03:21:40260 else
261 model_.SetShelfItemDelegate(id, nullptr);
262}
263
264void ShelfController::ShelfItemAdded(int index) {
Mike Wasserman5909b562018-02-20 18:00:46265 if (applying_remote_shelf_model_changes_)
msw19b30c2c2017-06-01 03:21:40266 return;
msw19b30c2c2017-06-01 03:21:40267
Mike Wassermanb4ed7eab2017-10-10 07:08:25268 // Pass null images to avoid transport costs; clients don't use images.
269 ShelfItem item = model_.items()[index];
270 item.image = gfx::ImageSkia();
msw19b30c2c2017-06-01 03:21:40271 observers_.ForAllPtrs([index, item](mojom::ShelfObserver* observer) {
272 observer->OnShelfItemAdded(index, item);
273 });
274}
275
276void ShelfController::ShelfItemRemoved(int index, const ShelfItem& old_item) {
Mike Wasserman5909b562018-02-20 18:00:46277 if (applying_remote_shelf_model_changes_)
msw19b30c2c2017-06-01 03:21:40278 return;
msw19b30c2c2017-06-01 03:21:40279
280 observers_.ForAllPtrs([old_item](mojom::ShelfObserver* observer) {
281 observer->OnShelfItemRemoved(old_item.id);
282 });
283}
284
285void ShelfController::ShelfItemMoved(int start_index, int target_index) {
Mike Wasserman5909b562018-02-20 18:00:46286 if (applying_remote_shelf_model_changes_)
msw19b30c2c2017-06-01 03:21:40287 return;
msw19b30c2c2017-06-01 03:21:40288
289 const ShelfItem& item = model_.items()[target_index];
290 observers_.ForAllPtrs([item, target_index](mojom::ShelfObserver* observer) {
291 observer->OnShelfItemMoved(item.id, target_index);
292 });
293}
294
295void ShelfController::ShelfItemChanged(int index, const ShelfItem& old_item) {
Mike Wasserman5909b562018-02-20 18:00:46296 if (applying_remote_shelf_model_changes_)
msw19b30c2c2017-06-01 03:21:40297 return;
msw19b30c2c2017-06-01 03:21:40298
Mike Wassermanb4ed7eab2017-10-10 07:08:25299 // Pass null images to avoid transport costs; clients don't use images.
300 ShelfItem item = model_.items()[index];
301 item.image = gfx::ImageSkia();
msw19b30c2c2017-06-01 03:21:40302 observers_.ForAllPtrs([item](mojom::ShelfObserver* observer) {
303 observer->OnShelfItemUpdated(item);
304 });
305}
306
307void ShelfController::ShelfItemDelegateChanged(const ShelfID& id,
khmel1240ee82017-10-05 23:48:18308 ShelfItemDelegate* old_delegate,
msw19b30c2c2017-06-01 03:21:40309 ShelfItemDelegate* delegate) {
Mike Wasserman5909b562018-02-20 18:00:46310 if (applying_remote_shelf_model_changes_)
msw19b30c2c2017-06-01 03:21:40311 return;
msw19b30c2c2017-06-01 03:21:40312
313 observers_.ForAllPtrs([id, delegate](mojom::ShelfObserver* observer) {
314 observer->OnShelfItemDelegateChanged(
315 id, delegate ? delegate->CreateInterfacePtrAndBind()
316 : mojom::ShelfItemDelegatePtr());
317 });
James Cookb0bf8e82017-04-09 17:01:44318}
319
Mike Wasserman0f1bd682017-10-11 18:20:58320void ShelfController::FlushForTesting() {
321 bindings_.FlushForTesting();
322}
323
Michael Wasserman39e4fe42017-08-08 23:49:42324void ShelfController::OnActiveUserPrefServiceChanged(
325 PrefService* pref_service) {
Michael Wasserman39e4fe42017-08-08 23:49:42326 SetShelfBehaviorsFromPrefs();
Mitsuru Oshima04b54d02017-10-09 14:22:45327 pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
Michael Wasserman39e4fe42017-08-08 23:49:42328 pref_change_registrar_->Init(pref_service);
329 pref_change_registrar_->Add(prefs::kShelfAlignmentLocal,
Qiang Xudadd3ad62018-03-07 17:22:45330 base::BindRepeating(&SetShelfAlignmentFromPrefs));
Michael Wasserman39e4fe42017-08-08 23:49:42331 pref_change_registrar_->Add(prefs::kShelfAutoHideBehaviorLocal,
Qiang Xudadd3ad62018-03-07 17:22:45332 base::BindRepeating(&SetShelfAutoHideFromPrefs));
Michael Wasserman39e4fe42017-08-08 23:49:42333 pref_change_registrar_->Add(prefs::kShelfPreferences,
Qiang Xudadd3ad62018-03-07 17:22:45334 base::BindRepeating(&SetShelfBehaviorsFromPrefs));
Michael Wasserman39e4fe42017-08-08 23:49:42335}
336
Qiang Xub7127da62017-08-29 01:44:57337void ShelfController::OnTabletModeStarted() {
Xiyuan Xia645b9282018-05-01 23:20:32338 // Do nothing when running in app mode.
339 if (Shell::Get()->session_controller()->IsRunningInAppMode())
340 return;
341
Sammie Quon40cdcc1a2017-09-21 22:25:49342 // Force the shelf to be visible and to be bottom aligned in tablet mode; the
343 // prefs are restored on exit.
Qiang Xub7127da62017-08-29 01:44:57344 for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
345 Shelf* shelf = GetShelfForDisplay(display.id());
Sammie Quon40cdcc1a2017-09-21 22:25:49346 if (shelf) {
Sammie Quona87fc322017-11-10 17:43:37347 // Only animate into tablet mode if the shelf alignment will not change.
348 if (shelf->IsHorizontalAlignment())
349 shelf->set_is_tablet_mode_animation_running(true);
Sammie Quon40cdcc1a2017-09-21 22:25:49350 shelf->SetAlignment(SHELF_ALIGNMENT_BOTTOM);
Sammie Quon8f7d4c12018-08-08 18:27:46351 shelf->shelf_widget()->OnTabletModeChanged();
Sammie Quon40cdcc1a2017-09-21 22:25:49352 }
Qiang Xub7127da62017-08-29 01:44:57353 }
354}
355
356void ShelfController::OnTabletModeEnded() {
Xiyuan Xia645b9282018-05-01 23:20:32357 // Do nothing when running in app mode.
358 if (Shell::Get()->session_controller()->IsRunningInAppMode())
359 return;
360
Sammie Quon40cdcc1a2017-09-21 22:25:49361 SetShelfBehaviorsFromPrefs();
Sammie Quona87fc322017-11-10 17:43:37362 // Only animate out of tablet mode if the shelf alignment will not change.
363 for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
364 Shelf* shelf = GetShelfForDisplay(display.id());
Sammie Quon8f7d4c12018-08-08 18:27:46365 if (shelf) {
366 if (shelf->IsHorizontalAlignment())
367 shelf->set_is_tablet_mode_animation_running(true);
368 shelf->shelf_widget()->OnTabletModeChanged();
369 }
Sammie Quona87fc322017-11-10 17:43:37370 }
Qiang Xub7127da62017-08-29 01:44:57371}
372
Michael Wasserman39e4fe42017-08-08 23:49:42373void ShelfController::OnDisplayConfigurationChanged() {
374 // Set/init the shelf behaviors from preferences, in case a display was added.
375 SetShelfBehaviorsFromPrefs();
Aga Wronska8af5e102018-05-18 16:45:03376
377 // Update shelf visibility to adapt to display changes. For instance shelf
378 // should be hidden on secondary display during inactive session states.
379 UpdateShelfVisibility();
Michael Wasserman39e4fe42017-08-08 23:49:42380}
381
382void ShelfController::OnWindowTreeHostReusedForDisplay(
383 AshWindowTreeHost* window_tree_host,
384 const display::Display& display) {
385 // See comment in OnWindowTreeHostsSwappedDisplays().
386 SetShelfBehaviorsFromPrefs();
Aga Wronska8af5e102018-05-18 16:45:03387
388 // Update shelf visibility to adapt to display changes. For instance shelf
389 // should be hidden on secondary display during inactive session states.
390 UpdateShelfVisibility();
Michael Wasserman39e4fe42017-08-08 23:49:42391}
392
393void ShelfController::OnWindowTreeHostsSwappedDisplays(
394 AshWindowTreeHost* host1,
395 AshWindowTreeHost* host2) {
396 // The display ids for existing shelf instances may have changed, so update
397 // the alignment and auto-hide state from prefs. See http://crbug.com/748291
398 SetShelfBehaviorsFromPrefs();
Aga Wronska8af5e102018-05-18 16:45:03399
400 // Update shelf visibility to adapt to display changes. For instance shelf
401 // should be hidden on secondary display during inactive session states.
402 UpdateShelfVisibility();
Michael Wasserman39e4fe42017-08-08 23:49:42403}
404
Alex Newcomerd929ca162018-01-18 23:24:47405void ShelfController::OnNotificationAdded(const std::string& notification_id) {
Alex Newcomerd7b0cc42018-05-25 22:58:48406 if (!is_notification_indicator_enabled_)
Alex Newcomerd929ca162018-01-18 23:24:47407 return;
408
409 message_center::Notification* notification =
410 message_center::MessageCenter::Get()->FindVisibleNotificationById(
411 notification_id);
Alex Newcomer9d92fcb92018-01-24 18:37:53412
Alex Newcomera3bcc9b2018-03-02 18:06:08413 if (!notification)
414 return;
415
416 // Skip this if the notification shouldn't badge an app.
417 if (notification->notifier_id().type !=
418 message_center::NotifierId::APPLICATION &&
419 notification->notifier_id().type !=
420 message_center::NotifierId::ARC_APPLICATION) {
Alex Newcomerd929ca162018-01-18 23:24:47421 return;
Alex Newcomer509bf672018-02-08 00:03:30422 }
Alex Newcomerd929ca162018-01-18 23:24:47423
Alex Newcomera3bcc9b2018-03-02 18:06:08424 // Skip this if the notification doesn't have a valid app id.
Xiyuan Xia474c66c2018-05-18 05:11:22425 if (notification->notifier_id().id == kDefaultArcNotifierId)
Alex Newcomera3bcc9b2018-03-02 18:06:08426 return;
427
Alex Newcomerd929ca162018-01-18 23:24:47428 model_.AddNotificationRecord(notification->notifier_id().id, notification_id);
429}
430
431void ShelfController::OnNotificationRemoved(const std::string& notification_id,
432 bool by_user) {
Alex Newcomerd7b0cc42018-05-25 22:58:48433 if (!is_notification_indicator_enabled_)
Alex Newcomerd929ca162018-01-18 23:24:47434 return;
435
436 model_.RemoveNotificationRecord(notification_id);
437}
438
James Cookb0bf8e82017-04-09 17:01:44439} // namespace ash