blob: 7f654999abe22bf249e760e6a6da9506c2ee2f92 [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/config.h"
11#include "ash/public/cpp/remote_shelf_item_delegate.h"
Michael Wasserman39e4fe42017-08-08 23:49:4212#include "ash/public/cpp/shelf_prefs.h"
James Cookb0bf8e82017-04-09 17:01:4413#include "ash/root_window_controller.h"
jamescook788b4fc2017-05-18 16:16:0614#include "ash/session/session_controller.h"
James Cookb0bf8e82017-04-09 17:01:4415#include "ash/shelf/app_list_shelf_item_delegate.h"
James Cook840177e2017-05-25 02:20:0116#include "ash/shelf/shelf.h"
Alex Newcomera3bcc9b2018-03-02 18:06:0817#include "ash/shelf/shelf_constants.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"
James Cookb0bf8e82017-04-09 17:01:4423#include "base/strings/utf_string_conversions.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() {
Sammie Quona9c65a42017-11-29 21:18:4296 // The shelf should always be bottom-aligned and not hidden in tablet mode;
97 // alignment and auto-hide are assigned from prefs when tablet mode is exited.
James Cookd2495fe2018-03-19 19:53:1098 if (Shell::Get()
99 ->tablet_mode_controller()
100 ->IsTabletModeWindowManagerEnabled()) {
Sammie Quona9c65a42017-11-29 21:18:42101 return;
102 }
103
Michael Wasserman39e4fe42017-08-08 23:49:42104 SetShelfAutoHideFromPrefs();
105 SetShelfAlignmentFromPrefs();
106}
107
James Cookb0bf8e82017-04-09 17:01:44108} // namespace
109
Alex Newcomerd929ca162018-01-18 23:24:47110ShelfController::ShelfController()
111 : is_touchable_app_context_menu_enabled_(
Alex Newcomer509bf672018-02-08 00:03:30112 features::IsTouchableAppContextMenuEnabled()),
Alex Newcomerd929ca162018-01-18 23:24:47113 message_center_observer_(this) {
Sammie Quon9b911f2f2017-12-15 02:53:15114 // Set the delegate and title string for the back button.
115 model_.SetShelfItemDelegate(ShelfID(kBackButtonId), nullptr);
116 DCHECK_EQ(0, model_.ItemIndexByID(ShelfID(kBackButtonId)));
117 ShelfItem back_item = model_.items()[0];
118 back_item.title = l10n_util::GetStringUTF16(IDS_ASH_SHELF_BACK_BUTTON_TITLE);
119 model_.Set(0, back_item);
120
msw109806d2017-06-02 20:11:57121 // Set the delegate and title string for the app list item.
msw19b30c2c2017-06-01 03:21:40122 model_.SetShelfItemDelegate(ShelfID(kAppListId),
Mitsuru Oshima04b54d02017-10-09 14:22:45123 std::make_unique<AppListShelfItemDelegate>());
Sammie Quon9b911f2f2017-12-15 02:53:15124 DCHECK_EQ(1, model_.ItemIndexByID(ShelfID(kAppListId)));
125 ShelfItem launcher_item = model_.items()[1];
126 launcher_item.title =
127 l10n_util::GetStringUTF16(IDS_ASH_SHELF_APP_LIST_LAUNCHER_TITLE);
128 model_.Set(1, launcher_item);
msw109806d2017-06-02 20:11:57129
msw19b30c2c2017-06-01 03:21:40130 model_.AddObserver(this);
Sam McNallyf4dab612017-08-16 03:06:33131 Shell::Get()->session_controller()->AddObserver(this);
Qiang Xub7127da62017-08-29 01:44:57132 Shell::Get()->tablet_mode_controller()->AddObserver(this);
Michael Wasserman39e4fe42017-08-08 23:49:42133 Shell::Get()->window_tree_host_manager()->AddObserver(this);
Alex Newcomerd929ca162018-01-18 23:24:47134 if (is_touchable_app_context_menu_enabled_)
135 message_center_observer_.Add(message_center::MessageCenter::Get());
James Cookb0bf8e82017-04-09 17:01:44136}
137
msw19b30c2c2017-06-01 03:21:40138ShelfController::~ShelfController() {
139 model_.RemoveObserver(this);
Mike Wasserman4cc9f402017-09-18 20:59:27140 model_.DestroyItemDelegates();
msw19b30c2c2017-06-01 03:21:40141}
James Cookb0bf8e82017-04-09 17:01:44142
James Cookd2495fe2018-03-19 19:53:10143void ShelfController::Shutdown() {
144 Shell::Get()->window_tree_host_manager()->RemoveObserver(this);
145 Shell::Get()->tablet_mode_controller()->RemoveObserver(this);
146 Shell::Get()->session_controller()->RemoveObserver(this);
147}
148
Michael Wasserman39e4fe42017-08-08 23:49:42149// static
150void ShelfController::RegisterProfilePrefs(PrefRegistrySimple* registry) {
James Cook5bd29692018-03-28 14:31:51151 // These prefs are public for ChromeLauncherController's OnIsSyncingChanged.
152 // See the pref names definitions for explanations of the synced, local, and
153 // per-display behaviors.
Michael Wasserman39e4fe42017-08-08 23:49:42154 registry->RegisterStringPref(
155 prefs::kShelfAutoHideBehavior, kShelfAutoHideBehaviorNever,
156 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
157 registry->RegisterStringPref(prefs::kShelfAutoHideBehaviorLocal,
158 std::string(), PrefRegistry::PUBLIC);
159 registry->RegisterStringPref(
160 prefs::kShelfAlignment, kShelfAlignmentBottom,
161 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
162 registry->RegisterStringPref(prefs::kShelfAlignmentLocal, std::string(),
163 PrefRegistry::PUBLIC);
164 registry->RegisterDictionaryPref(prefs::kShelfPreferences,
165 PrefRegistry::PUBLIC);
166}
167
James Cookb0bf8e82017-04-09 17:01:44168void ShelfController::BindRequest(mojom::ShelfControllerRequest request) {
169 bindings_.AddBinding(this, std::move(request));
170}
171
James Cookb0bf8e82017-04-09 17:01:44172void ShelfController::AddObserver(
173 mojom::ShelfObserverAssociatedPtrInfo observer) {
174 mojom::ShelfObserverAssociatedPtr observer_ptr;
175 observer_ptr.Bind(std::move(observer));
msw19b30c2c2017-06-01 03:21:40176
Mike Wasserman5909b562018-02-20 18:00:46177 // Synchronize two ShelfModel instances, one each owned by Ash and Chrome.
178 // Notify Chrome of existing ShelfModel items and delegates created by Ash.
179 for (int i = 0; i < model_.item_count(); ++i) {
180 ShelfItem item = model_.items()[i];
181 ShelfItemDelegate* delegate = model_.GetShelfItemDelegate(item.id);
182 // Notify observers of the delegate before the items themselves; Chrome
183 // creates default delegates if none exist, breaking ShelfWindowWatcher.
184 if (delegate) {
185 observer_ptr->OnShelfItemDelegateChanged(
186 item.id, delegate->CreateInterfacePtrAndBind());
msw19b30c2c2017-06-01 03:21:40187 }
Mike Wasserman5909b562018-02-20 18:00:46188 // Pass null images to avoid transport costs; clients don't use images.
189 item.image = gfx::ImageSkia();
190 observer_ptr->OnShelfItemAdded(i, item);
msw19b30c2c2017-06-01 03:21:40191 }
192
James Cookb0bf8e82017-04-09 17:01:44193 observers_.AddPtr(std::move(observer_ptr));
194}
195
msw19b30c2c2017-06-01 03:21:40196void ShelfController::AddShelfItem(int32_t index, const ShelfItem& item) {
msw70ac45f2017-06-05 02:02:45197 DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
msw19b30c2c2017-06-01 03:21:40198 index = index < 0 ? model_.item_count() : index;
Julien Brianceau293917a82017-08-01 17:32:59199 DCHECK_GT(index, 0) << " Items can not precede the AppList";
msw70ac45f2017-06-05 02:02:45200 DCHECK_LE(index, model_.item_count()) << " Index out of bounds";
msw19b30c2c2017-06-01 03:21:40201 index = std::min(std::max(index, 1), model_.item_count());
202 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
203 model_.AddAt(index, item);
James Cookb0bf8e82017-04-09 17:01:44204}
205
msw19b30c2c2017-06-01 03:21:40206void ShelfController::RemoveShelfItem(const ShelfID& id) {
msw70ac45f2017-06-05 02:02:45207 DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
msw19b30c2c2017-06-01 03:21:40208 const int index = model_.ItemIndexByID(id);
msw70ac45f2017-06-05 02:02:45209 DCHECK_GE(index, 0) << " No item found with the id: " << id;
210 DCHECK_NE(index, 0) << " The AppList shelf item cannot be removed";
msw19b30c2c2017-06-01 03:21:40211 if (index <= 0)
212 return;
213 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
214 model_.RemoveItemAt(index);
James Cookb0bf8e82017-04-09 17:01:44215}
216
msw19b30c2c2017-06-01 03:21:40217void ShelfController::MoveShelfItem(const ShelfID& id, int32_t index) {
msw70ac45f2017-06-05 02:02:45218 DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
msw19b30c2c2017-06-01 03:21:40219 const int current_index = model_.ItemIndexByID(id);
msw70ac45f2017-06-05 02:02:45220 DCHECK_GE(current_index, 0) << " No item found with the id: " << id;
221 DCHECK_NE(current_index, 0) << " The AppList shelf item cannot be moved";
msw19b30c2c2017-06-01 03:21:40222 if (current_index <= 0)
223 return;
Julien Brianceau293917a82017-08-01 17:32:59224 DCHECK_GT(index, 0) << " Items can not precede the AppList";
msw70ac45f2017-06-05 02:02:45225 DCHECK_LT(index, model_.item_count()) << " Index out of bounds";
msw19b30c2c2017-06-01 03:21:40226 index = std::min(std::max(index, 1), model_.item_count() - 1);
Mike Wassermanf0145092017-09-29 01:30:54227 if (current_index == index) {
228 DVLOG(1) << "The item is already at the given index (" << index << "). "
229 << "This happens when syncing a ShelfModel weight reordering.";
msw19b30c2c2017-06-01 03:21:40230 return;
Mike Wassermanf0145092017-09-29 01:30:54231 }
msw19b30c2c2017-06-01 03:21:40232 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
233 model_.Move(current_index, index);
234}
235
236void ShelfController::UpdateShelfItem(const ShelfItem& item) {
msw70ac45f2017-06-05 02:02:45237 DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
msw19b30c2c2017-06-01 03:21:40238 const int index = model_.ItemIndexByID(item.id);
msw70ac45f2017-06-05 02:02:45239 DCHECK_GE(index, 0) << " No item found with the id: " << item.id;
msw19b30c2c2017-06-01 03:21:40240 if (index < 0)
241 return;
242 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
Mike Wassermanb4ed7eab2017-10-10 07:08:25243
244 // Keep any existing image if the item was sent without one for efficiency.
Xiyuan Xia474c66c2018-05-18 05:11:22245 ShelfItem new_item = item;
Mike Wassermanb4ed7eab2017-10-10 07:08:25246 if (item.image.isNull())
247 new_item.image = model_.items()[index].image;
248 model_.Set(index, new_item);
msw19b30c2c2017-06-01 03:21:40249}
250
251void ShelfController::SetShelfItemDelegate(
252 const ShelfID& id,
253 mojom::ShelfItemDelegatePtr delegate) {
msw70ac45f2017-06-05 02:02:45254 DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
msw19b30c2c2017-06-01 03:21:40255 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
256 if (delegate.is_bound())
257 model_.SetShelfItemDelegate(
Mitsuru Oshima04b54d02017-10-09 14:22:45258 id, std::make_unique<RemoteShelfItemDelegate>(id, std::move(delegate)));
msw19b30c2c2017-06-01 03:21:40259 else
260 model_.SetShelfItemDelegate(id, nullptr);
261}
262
263void ShelfController::ShelfItemAdded(int index) {
Mike Wasserman5909b562018-02-20 18:00:46264 if (applying_remote_shelf_model_changes_)
msw19b30c2c2017-06-01 03:21:40265 return;
msw19b30c2c2017-06-01 03:21:40266
Mike Wassermanb4ed7eab2017-10-10 07:08:25267 // Pass null images to avoid transport costs; clients don't use images.
268 ShelfItem item = model_.items()[index];
269 item.image = gfx::ImageSkia();
msw19b30c2c2017-06-01 03:21:40270 observers_.ForAllPtrs([index, item](mojom::ShelfObserver* observer) {
271 observer->OnShelfItemAdded(index, item);
272 });
273}
274
275void ShelfController::ShelfItemRemoved(int index, const ShelfItem& old_item) {
Mike Wasserman5909b562018-02-20 18:00:46276 if (applying_remote_shelf_model_changes_)
msw19b30c2c2017-06-01 03:21:40277 return;
msw19b30c2c2017-06-01 03:21:40278
279 observers_.ForAllPtrs([old_item](mojom::ShelfObserver* observer) {
280 observer->OnShelfItemRemoved(old_item.id);
281 });
282}
283
284void ShelfController::ShelfItemMoved(int start_index, int target_index) {
Mike Wasserman5909b562018-02-20 18:00:46285 if (applying_remote_shelf_model_changes_)
msw19b30c2c2017-06-01 03:21:40286 return;
msw19b30c2c2017-06-01 03:21:40287
288 const ShelfItem& item = model_.items()[target_index];
289 observers_.ForAllPtrs([item, target_index](mojom::ShelfObserver* observer) {
290 observer->OnShelfItemMoved(item.id, target_index);
291 });
292}
293
294void ShelfController::ShelfItemChanged(int index, const ShelfItem& old_item) {
Mike Wasserman5909b562018-02-20 18:00:46295 if (applying_remote_shelf_model_changes_)
msw19b30c2c2017-06-01 03:21:40296 return;
msw19b30c2c2017-06-01 03:21:40297
Mike Wassermanb4ed7eab2017-10-10 07:08:25298 // Pass null images to avoid transport costs; clients don't use images.
299 ShelfItem item = model_.items()[index];
300 item.image = gfx::ImageSkia();
msw19b30c2c2017-06-01 03:21:40301 observers_.ForAllPtrs([item](mojom::ShelfObserver* observer) {
302 observer->OnShelfItemUpdated(item);
303 });
304}
305
306void ShelfController::ShelfItemDelegateChanged(const ShelfID& id,
khmel1240ee82017-10-05 23:48:18307 ShelfItemDelegate* old_delegate,
msw19b30c2c2017-06-01 03:21:40308 ShelfItemDelegate* delegate) {
Mike Wasserman5909b562018-02-20 18:00:46309 if (applying_remote_shelf_model_changes_)
msw19b30c2c2017-06-01 03:21:40310 return;
msw19b30c2c2017-06-01 03:21:40311
312 observers_.ForAllPtrs([id, delegate](mojom::ShelfObserver* observer) {
313 observer->OnShelfItemDelegateChanged(
314 id, delegate ? delegate->CreateInterfacePtrAndBind()
315 : mojom::ShelfItemDelegatePtr());
316 });
James Cookb0bf8e82017-04-09 17:01:44317}
318
Mike Wasserman0f1bd682017-10-11 18:20:58319void ShelfController::FlushForTesting() {
320 bindings_.FlushForTesting();
321}
322
Michael Wasserman39e4fe42017-08-08 23:49:42323void ShelfController::OnActiveUserPrefServiceChanged(
324 PrefService* pref_service) {
Michael Wasserman39e4fe42017-08-08 23:49:42325 SetShelfBehaviorsFromPrefs();
Mitsuru Oshima04b54d02017-10-09 14:22:45326 pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
Michael Wasserman39e4fe42017-08-08 23:49:42327 pref_change_registrar_->Init(pref_service);
328 pref_change_registrar_->Add(prefs::kShelfAlignmentLocal,
Qiang Xudadd3ad62018-03-07 17:22:45329 base::BindRepeating(&SetShelfAlignmentFromPrefs));
Michael Wasserman39e4fe42017-08-08 23:49:42330 pref_change_registrar_->Add(prefs::kShelfAutoHideBehaviorLocal,
Qiang Xudadd3ad62018-03-07 17:22:45331 base::BindRepeating(&SetShelfAutoHideFromPrefs));
Michael Wasserman39e4fe42017-08-08 23:49:42332 pref_change_registrar_->Add(prefs::kShelfPreferences,
Qiang Xudadd3ad62018-03-07 17:22:45333 base::BindRepeating(&SetShelfBehaviorsFromPrefs));
Michael Wasserman39e4fe42017-08-08 23:49:42334}
335
Qiang Xub7127da62017-08-29 01:44:57336void ShelfController::OnTabletModeStarted() {
Xiyuan Xia645b9282018-05-01 23:20:32337 // Do nothing when running in app mode.
338 if (Shell::Get()->session_controller()->IsRunningInAppMode())
339 return;
340
Sammie Quon40cdcc1a2017-09-21 22:25:49341 // Force the shelf to be visible and to be bottom aligned in tablet mode; the
342 // prefs are restored on exit.
Qiang Xub7127da62017-08-29 01:44:57343 for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
344 Shelf* shelf = GetShelfForDisplay(display.id());
Sammie Quon40cdcc1a2017-09-21 22:25:49345 if (shelf) {
Sammie Quona87fc322017-11-10 17:43:37346 // Only animate into tablet mode if the shelf alignment will not change.
347 if (shelf->IsHorizontalAlignment())
348 shelf->set_is_tablet_mode_animation_running(true);
Qiang Xub7127da62017-08-29 01:44:57349 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
Sammie Quon40cdcc1a2017-09-21 22:25:49350 shelf->SetAlignment(SHELF_ALIGNMENT_BOTTOM);
351 }
Qiang Xub7127da62017-08-29 01:44:57352 }
353}
354
355void ShelfController::OnTabletModeEnded() {
Xiyuan Xia645b9282018-05-01 23:20:32356 // Do nothing when running in app mode.
357 if (Shell::Get()->session_controller()->IsRunningInAppMode())
358 return;
359
Sammie Quon40cdcc1a2017-09-21 22:25:49360 SetShelfBehaviorsFromPrefs();
Sammie Quona87fc322017-11-10 17:43:37361 // Only animate out of tablet mode if the shelf alignment will not change.
362 for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
363 Shelf* shelf = GetShelfForDisplay(display.id());
364 if (shelf && shelf->IsHorizontalAlignment())
365 shelf->set_is_tablet_mode_animation_running(true);
366 }
Qiang Xub7127da62017-08-29 01:44:57367}
368
Michael Wasserman39e4fe42017-08-08 23:49:42369void ShelfController::OnDisplayConfigurationChanged() {
370 // Set/init the shelf behaviors from preferences, in case a display was added.
371 SetShelfBehaviorsFromPrefs();
Aga Wronska8af5e102018-05-18 16:45:03372
373 // Update shelf visibility to adapt to display changes. For instance shelf
374 // should be hidden on secondary display during inactive session states.
375 UpdateShelfVisibility();
Michael Wasserman39e4fe42017-08-08 23:49:42376}
377
378void ShelfController::OnWindowTreeHostReusedForDisplay(
379 AshWindowTreeHost* window_tree_host,
380 const display::Display& display) {
381 // See comment in OnWindowTreeHostsSwappedDisplays().
382 SetShelfBehaviorsFromPrefs();
Aga Wronska8af5e102018-05-18 16:45:03383
384 // Update shelf visibility to adapt to display changes. For instance shelf
385 // should be hidden on secondary display during inactive session states.
386 UpdateShelfVisibility();
Michael Wasserman39e4fe42017-08-08 23:49:42387}
388
389void ShelfController::OnWindowTreeHostsSwappedDisplays(
390 AshWindowTreeHost* host1,
391 AshWindowTreeHost* host2) {
392 // The display ids for existing shelf instances may have changed, so update
393 // the alignment and auto-hide state from prefs. See http://crbug.com/748291
394 SetShelfBehaviorsFromPrefs();
Aga Wronska8af5e102018-05-18 16:45:03395
396 // Update shelf visibility to adapt to display changes. For instance shelf
397 // should be hidden on secondary display during inactive session states.
398 UpdateShelfVisibility();
Michael Wasserman39e4fe42017-08-08 23:49:42399}
400
Alex Newcomerd929ca162018-01-18 23:24:47401void ShelfController::OnNotificationAdded(const std::string& notification_id) {
402 if (!is_touchable_app_context_menu_enabled_)
403 return;
404
405 message_center::Notification* notification =
406 message_center::MessageCenter::Get()->FindVisibleNotificationById(
407 notification_id);
Alex Newcomer9d92fcb92018-01-24 18:37:53408
Alex Newcomera3bcc9b2018-03-02 18:06:08409 if (!notification)
410 return;
411
412 // Skip this if the notification shouldn't badge an app.
413 if (notification->notifier_id().type !=
414 message_center::NotifierId::APPLICATION &&
415 notification->notifier_id().type !=
416 message_center::NotifierId::ARC_APPLICATION) {
Alex Newcomerd929ca162018-01-18 23:24:47417 return;
Alex Newcomer509bf672018-02-08 00:03:30418 }
Alex Newcomerd929ca162018-01-18 23:24:47419
Alex Newcomera3bcc9b2018-03-02 18:06:08420 // Skip this if the notification doesn't have a valid app id.
Xiyuan Xia474c66c2018-05-18 05:11:22421 if (notification->notifier_id().id == kDefaultArcNotifierId)
Alex Newcomera3bcc9b2018-03-02 18:06:08422 return;
423
Alex Newcomerd929ca162018-01-18 23:24:47424 model_.AddNotificationRecord(notification->notifier_id().id, notification_id);
425}
426
427void ShelfController::OnNotificationRemoved(const std::string& notification_id,
428 bool by_user) {
429 if (!is_touchable_app_context_menu_enabled_)
430 return;
431
432 model_.RemoveNotificationRecord(notification_id);
433}
434
James Cookb0bf8e82017-04-09 17:01:44435} // namespace ash