blob: 0ca5a4fb2e412ec935ece22891f77b93a2360d5e [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"
Qiang Xub7127da62017-08-29 01:44:5720#include "ash/wm/tablet_mode/tablet_mode_controller.h"
msw19b30c2c2017-06-01 03:21:4021#include "base/auto_reset.h"
James Cookb0bf8e82017-04-09 17:01:4422#include "base/strings/utf_string_conversions.h"
Michael Wasserman39e4fe42017-08-08 23:49:4223#include "components/pref_registry/pref_registry_syncable.h"
24#include "components/prefs/pref_change_registrar.h"
25#include "components/prefs/pref_registry_simple.h"
26#include "components/prefs/pref_service.h"
msw109806d2017-06-02 20:11:5727#include "ui/base/l10n/l10n_util.h"
James Cookb0bf8e82017-04-09 17:01:4428#include "ui/base/models/simple_menu_model.h"
Alex Newcomer509bf672018-02-08 00:03:3029#include "ui/base/ui_base_features.h"
James Cookb0bf8e82017-04-09 17:01:4430#include "ui/display/display.h"
31#include "ui/display/screen.h"
Alex Newcomerd929ca162018-01-18 23:24:4732#include "ui/message_center/message_center.h"
James Cookb0bf8e82017-04-09 17:01:4433
34namespace ash {
35
36namespace {
37
James Cook840177e2017-05-25 02:20:0138// Returns the Shelf instance for the display with the given |display_id|.
39Shelf* GetShelfForDisplay(int64_t display_id) {
James Cookb0bf8e82017-04-09 17:01:4440 // The controller may be null for invalid ids or for displays being removed.
41 RootWindowController* root_window_controller =
42 Shell::GetRootWindowControllerWithDisplayId(display_id);
jamescookaa9f49f2017-05-30 20:48:4543 return root_window_controller ? root_window_controller->shelf() : nullptr;
James Cookb0bf8e82017-04-09 17:01:4444}
45
Michael Wasserman39e4fe42017-08-08 23:49:4246// Set each Shelf's auto-hide behavior from the per-display pref.
47void SetShelfAutoHideFromPrefs() {
48 // TODO(jamescook): The session state check should not be necessary, but
49 // otherwise this wrongly tries to set the alignment on a secondary display
50 // during login before the ShelfLockingManager is created.
51 SessionController* session_controller = Shell::Get()->session_controller();
Sam McNallyf4dab612017-08-16 03:06:3352 PrefService* prefs = session_controller->GetLastActiveUserPrefService();
Michael Wasserman39e4fe42017-08-08 23:49:4253 if (!prefs || !session_controller->IsActiveUserSessionStarted())
54 return;
55
56 for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
57 auto value = GetShelfAutoHideBehaviorPref(prefs, display.id());
58 // Don't show the shelf in app mode.
59 if (session_controller->IsRunningInAppMode())
60 value = SHELF_AUTO_HIDE_ALWAYS_HIDDEN;
61 Shelf* shelf = GetShelfForDisplay(display.id());
62 if (shelf)
63 shelf->SetAutoHideBehavior(value);
64 }
65}
66
67// Set each Shelf's alignment from the per-display pref.
68void SetShelfAlignmentFromPrefs() {
69 // TODO(jamescook): The session state check should not be necessary, but
70 // otherwise this wrongly tries to set the alignment on a secondary display
71 // during login before the ShelfLockingManager is created.
72 SessionController* session_controller = Shell::Get()->session_controller();
Sam McNallyf4dab612017-08-16 03:06:3373 PrefService* prefs = session_controller->GetLastActiveUserPrefService();
Michael Wasserman39e4fe42017-08-08 23:49:4274 if (!prefs || !session_controller->IsActiveUserSessionStarted())
75 return;
76
77 for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
78 auto value = GetShelfAlignmentPref(prefs, display.id());
79 Shelf* shelf = GetShelfForDisplay(display.id());
80 if (shelf)
81 shelf->SetAlignment(value);
82 }
83}
84
85// Set each Shelf's auto-hide behavior and alignment from the per-display prefs.
86void SetShelfBehaviorsFromPrefs() {
Sammie Quona9c65a42017-11-29 21:18:4287 // The shelf should always be bottom-aligned and not hidden in tablet mode;
88 // alignment and auto-hide are assigned from prefs when tablet mode is exited.
James Cookd2495fe2018-03-19 19:53:1089 if (Shell::Get()
90 ->tablet_mode_controller()
91 ->IsTabletModeWindowManagerEnabled()) {
Sammie Quona9c65a42017-11-29 21:18:4292 return;
93 }
94
Michael Wasserman39e4fe42017-08-08 23:49:4295 SetShelfAutoHideFromPrefs();
96 SetShelfAlignmentFromPrefs();
97}
98
James Cookb0bf8e82017-04-09 17:01:4499} // namespace
100
Alex Newcomerd929ca162018-01-18 23:24:47101ShelfController::ShelfController()
102 : is_touchable_app_context_menu_enabled_(
Alex Newcomer509bf672018-02-08 00:03:30103 features::IsTouchableAppContextMenuEnabled()),
Alex Newcomerd929ca162018-01-18 23:24:47104 message_center_observer_(this) {
Sammie Quon9b911f2f2017-12-15 02:53:15105 // Set the delegate and title string for the back button.
106 model_.SetShelfItemDelegate(ShelfID(kBackButtonId), nullptr);
107 DCHECK_EQ(0, model_.ItemIndexByID(ShelfID(kBackButtonId)));
108 ShelfItem back_item = model_.items()[0];
109 back_item.title = l10n_util::GetStringUTF16(IDS_ASH_SHELF_BACK_BUTTON_TITLE);
110 model_.Set(0, back_item);
111
msw109806d2017-06-02 20:11:57112 // Set the delegate and title string for the app list item.
msw19b30c2c2017-06-01 03:21:40113 model_.SetShelfItemDelegate(ShelfID(kAppListId),
Mitsuru Oshima04b54d02017-10-09 14:22:45114 std::make_unique<AppListShelfItemDelegate>());
Sammie Quon9b911f2f2017-12-15 02:53:15115 DCHECK_EQ(1, model_.ItemIndexByID(ShelfID(kAppListId)));
116 ShelfItem launcher_item = model_.items()[1];
117 launcher_item.title =
118 l10n_util::GetStringUTF16(IDS_ASH_SHELF_APP_LIST_LAUNCHER_TITLE);
119 model_.Set(1, launcher_item);
msw109806d2017-06-02 20:11:57120
msw19b30c2c2017-06-01 03:21:40121 model_.AddObserver(this);
Sam McNallyf4dab612017-08-16 03:06:33122 Shell::Get()->session_controller()->AddObserver(this);
Qiang Xub7127da62017-08-29 01:44:57123 Shell::Get()->tablet_mode_controller()->AddObserver(this);
Michael Wasserman39e4fe42017-08-08 23:49:42124 Shell::Get()->window_tree_host_manager()->AddObserver(this);
Alex Newcomerd929ca162018-01-18 23:24:47125 if (is_touchable_app_context_menu_enabled_)
126 message_center_observer_.Add(message_center::MessageCenter::Get());
James Cookb0bf8e82017-04-09 17:01:44127}
128
msw19b30c2c2017-06-01 03:21:40129ShelfController::~ShelfController() {
130 model_.RemoveObserver(this);
Mike Wasserman4cc9f402017-09-18 20:59:27131 model_.DestroyItemDelegates();
msw19b30c2c2017-06-01 03:21:40132}
James Cookb0bf8e82017-04-09 17:01:44133
James Cookd2495fe2018-03-19 19:53:10134void ShelfController::Shutdown() {
135 Shell::Get()->window_tree_host_manager()->RemoveObserver(this);
136 Shell::Get()->tablet_mode_controller()->RemoveObserver(this);
137 Shell::Get()->session_controller()->RemoveObserver(this);
138}
139
Michael Wasserman39e4fe42017-08-08 23:49:42140// static
141void ShelfController::RegisterProfilePrefs(PrefRegistrySimple* registry) {
Mike Wasserman7e4404432017-10-16 16:59:11142 // These prefs are public for ChromeLauncherController's OnIsSyncingChanged
143 // and ShelfBoundsChangesProbablyWithUser. See the pref names definitions for
144 // explanations of the synced, local, and per-display behaviors.
Michael Wasserman39e4fe42017-08-08 23:49:42145 registry->RegisterStringPref(
146 prefs::kShelfAutoHideBehavior, kShelfAutoHideBehaviorNever,
147 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
148 registry->RegisterStringPref(prefs::kShelfAutoHideBehaviorLocal,
149 std::string(), PrefRegistry::PUBLIC);
150 registry->RegisterStringPref(
151 prefs::kShelfAlignment, kShelfAlignmentBottom,
152 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
153 registry->RegisterStringPref(prefs::kShelfAlignmentLocal, std::string(),
154 PrefRegistry::PUBLIC);
155 registry->RegisterDictionaryPref(prefs::kShelfPreferences,
156 PrefRegistry::PUBLIC);
157}
158
James Cookb0bf8e82017-04-09 17:01:44159void ShelfController::BindRequest(mojom::ShelfControllerRequest request) {
160 bindings_.AddBinding(this, std::move(request));
161}
162
James Cookb0bf8e82017-04-09 17:01:44163void ShelfController::AddObserver(
164 mojom::ShelfObserverAssociatedPtrInfo observer) {
165 mojom::ShelfObserverAssociatedPtr observer_ptr;
166 observer_ptr.Bind(std::move(observer));
msw19b30c2c2017-06-01 03:21:40167
Mike Wasserman5909b562018-02-20 18:00:46168 // Synchronize two ShelfModel instances, one each owned by Ash and Chrome.
169 // Notify Chrome of existing ShelfModel items and delegates created by Ash.
170 for (int i = 0; i < model_.item_count(); ++i) {
171 ShelfItem item = model_.items()[i];
172 ShelfItemDelegate* delegate = model_.GetShelfItemDelegate(item.id);
173 // Notify observers of the delegate before the items themselves; Chrome
174 // creates default delegates if none exist, breaking ShelfWindowWatcher.
175 if (delegate) {
176 observer_ptr->OnShelfItemDelegateChanged(
177 item.id, delegate->CreateInterfacePtrAndBind());
msw19b30c2c2017-06-01 03:21:40178 }
Mike Wasserman5909b562018-02-20 18:00:46179 // Pass null images to avoid transport costs; clients don't use images.
180 item.image = gfx::ImageSkia();
181 observer_ptr->OnShelfItemAdded(i, item);
msw19b30c2c2017-06-01 03:21:40182 }
183
James Cookb0bf8e82017-04-09 17:01:44184 observers_.AddPtr(std::move(observer_ptr));
185}
186
msw19b30c2c2017-06-01 03:21:40187void ShelfController::AddShelfItem(int32_t index, const ShelfItem& item) {
msw70ac45f2017-06-05 02:02:45188 DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
msw19b30c2c2017-06-01 03:21:40189 index = index < 0 ? model_.item_count() : index;
Julien Brianceau293917a82017-08-01 17:32:59190 DCHECK_GT(index, 0) << " Items can not precede the AppList";
msw70ac45f2017-06-05 02:02:45191 DCHECK_LE(index, model_.item_count()) << " Index out of bounds";
msw19b30c2c2017-06-01 03:21:40192 index = std::min(std::max(index, 1), model_.item_count());
193 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
194 model_.AddAt(index, item);
James Cookb0bf8e82017-04-09 17:01:44195}
196
msw19b30c2c2017-06-01 03:21:40197void ShelfController::RemoveShelfItem(const ShelfID& id) {
msw70ac45f2017-06-05 02:02:45198 DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
msw19b30c2c2017-06-01 03:21:40199 const int index = model_.ItemIndexByID(id);
msw70ac45f2017-06-05 02:02:45200 DCHECK_GE(index, 0) << " No item found with the id: " << id;
201 DCHECK_NE(index, 0) << " The AppList shelf item cannot be removed";
msw19b30c2c2017-06-01 03:21:40202 if (index <= 0)
203 return;
204 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
205 model_.RemoveItemAt(index);
James Cookb0bf8e82017-04-09 17:01:44206}
207
msw19b30c2c2017-06-01 03:21:40208void ShelfController::MoveShelfItem(const ShelfID& id, int32_t index) {
msw70ac45f2017-06-05 02:02:45209 DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
msw19b30c2c2017-06-01 03:21:40210 const int current_index = model_.ItemIndexByID(id);
msw70ac45f2017-06-05 02:02:45211 DCHECK_GE(current_index, 0) << " No item found with the id: " << id;
212 DCHECK_NE(current_index, 0) << " The AppList shelf item cannot be moved";
msw19b30c2c2017-06-01 03:21:40213 if (current_index <= 0)
214 return;
Julien Brianceau293917a82017-08-01 17:32:59215 DCHECK_GT(index, 0) << " Items can not precede the AppList";
msw70ac45f2017-06-05 02:02:45216 DCHECK_LT(index, model_.item_count()) << " Index out of bounds";
msw19b30c2c2017-06-01 03:21:40217 index = std::min(std::max(index, 1), model_.item_count() - 1);
Mike Wassermanf0145092017-09-29 01:30:54218 if (current_index == index) {
219 DVLOG(1) << "The item is already at the given index (" << index << "). "
220 << "This happens when syncing a ShelfModel weight reordering.";
msw19b30c2c2017-06-01 03:21:40221 return;
Mike Wassermanf0145092017-09-29 01:30:54222 }
msw19b30c2c2017-06-01 03:21:40223 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
224 model_.Move(current_index, index);
225}
226
227void ShelfController::UpdateShelfItem(const ShelfItem& item) {
msw70ac45f2017-06-05 02:02:45228 DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
msw19b30c2c2017-06-01 03:21:40229 const int index = model_.ItemIndexByID(item.id);
msw70ac45f2017-06-05 02:02:45230 DCHECK_GE(index, 0) << " No item found with the id: " << item.id;
msw19b30c2c2017-06-01 03:21:40231 if (index < 0)
232 return;
233 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
Mike Wassermanb4ed7eab2017-10-10 07:08:25234
235 // Keep any existing image if the item was sent without one for efficiency.
236 ash::ShelfItem new_item = item;
237 if (item.image.isNull())
238 new_item.image = model_.items()[index].image;
239 model_.Set(index, new_item);
msw19b30c2c2017-06-01 03:21:40240}
241
242void ShelfController::SetShelfItemDelegate(
243 const ShelfID& id,
244 mojom::ShelfItemDelegatePtr delegate) {
msw70ac45f2017-06-05 02:02:45245 DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
msw19b30c2c2017-06-01 03:21:40246 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
247 if (delegate.is_bound())
248 model_.SetShelfItemDelegate(
Mitsuru Oshima04b54d02017-10-09 14:22:45249 id, std::make_unique<RemoteShelfItemDelegate>(id, std::move(delegate)));
msw19b30c2c2017-06-01 03:21:40250 else
251 model_.SetShelfItemDelegate(id, nullptr);
252}
253
254void ShelfController::ShelfItemAdded(int index) {
Mike Wasserman5909b562018-02-20 18:00:46255 if (applying_remote_shelf_model_changes_)
msw19b30c2c2017-06-01 03:21:40256 return;
msw19b30c2c2017-06-01 03:21:40257
Mike Wassermanb4ed7eab2017-10-10 07:08:25258 // Pass null images to avoid transport costs; clients don't use images.
259 ShelfItem item = model_.items()[index];
260 item.image = gfx::ImageSkia();
msw19b30c2c2017-06-01 03:21:40261 observers_.ForAllPtrs([index, item](mojom::ShelfObserver* observer) {
262 observer->OnShelfItemAdded(index, item);
263 });
264}
265
266void ShelfController::ShelfItemRemoved(int index, const ShelfItem& old_item) {
Mike Wasserman5909b562018-02-20 18:00:46267 if (applying_remote_shelf_model_changes_)
msw19b30c2c2017-06-01 03:21:40268 return;
msw19b30c2c2017-06-01 03:21:40269
270 observers_.ForAllPtrs([old_item](mojom::ShelfObserver* observer) {
271 observer->OnShelfItemRemoved(old_item.id);
272 });
273}
274
275void ShelfController::ShelfItemMoved(int start_index, int target_index) {
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 const ShelfItem& item = model_.items()[target_index];
280 observers_.ForAllPtrs([item, target_index](mojom::ShelfObserver* observer) {
281 observer->OnShelfItemMoved(item.id, target_index);
282 });
283}
284
285void ShelfController::ShelfItemChanged(int index, const ShelfItem& old_item) {
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
Mike Wassermanb4ed7eab2017-10-10 07:08:25289 // Pass null images to avoid transport costs; clients don't use images.
290 ShelfItem item = model_.items()[index];
291 item.image = gfx::ImageSkia();
msw19b30c2c2017-06-01 03:21:40292 observers_.ForAllPtrs([item](mojom::ShelfObserver* observer) {
293 observer->OnShelfItemUpdated(item);
294 });
295}
296
297void ShelfController::ShelfItemDelegateChanged(const ShelfID& id,
khmel1240ee82017-10-05 23:48:18298 ShelfItemDelegate* old_delegate,
msw19b30c2c2017-06-01 03:21:40299 ShelfItemDelegate* delegate) {
Mike Wasserman5909b562018-02-20 18:00:46300 if (applying_remote_shelf_model_changes_)
msw19b30c2c2017-06-01 03:21:40301 return;
msw19b30c2c2017-06-01 03:21:40302
303 observers_.ForAllPtrs([id, delegate](mojom::ShelfObserver* observer) {
304 observer->OnShelfItemDelegateChanged(
305 id, delegate ? delegate->CreateInterfacePtrAndBind()
306 : mojom::ShelfItemDelegatePtr());
307 });
James Cookb0bf8e82017-04-09 17:01:44308}
309
Mike Wasserman0f1bd682017-10-11 18:20:58310void ShelfController::FlushForTesting() {
311 bindings_.FlushForTesting();
312}
313
Michael Wasserman39e4fe42017-08-08 23:49:42314void ShelfController::OnActiveUserPrefServiceChanged(
315 PrefService* pref_service) {
Michael Wasserman39e4fe42017-08-08 23:49:42316 SetShelfBehaviorsFromPrefs();
Mitsuru Oshima04b54d02017-10-09 14:22:45317 pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
Michael Wasserman39e4fe42017-08-08 23:49:42318 pref_change_registrar_->Init(pref_service);
319 pref_change_registrar_->Add(prefs::kShelfAlignmentLocal,
Qiang Xudadd3ad62018-03-07 17:22:45320 base::BindRepeating(&SetShelfAlignmentFromPrefs));
Michael Wasserman39e4fe42017-08-08 23:49:42321 pref_change_registrar_->Add(prefs::kShelfAutoHideBehaviorLocal,
Qiang Xudadd3ad62018-03-07 17:22:45322 base::BindRepeating(&SetShelfAutoHideFromPrefs));
Michael Wasserman39e4fe42017-08-08 23:49:42323 pref_change_registrar_->Add(prefs::kShelfPreferences,
Qiang Xudadd3ad62018-03-07 17:22:45324 base::BindRepeating(&SetShelfBehaviorsFromPrefs));
Michael Wasserman39e4fe42017-08-08 23:49:42325}
326
Qiang Xub7127da62017-08-29 01:44:57327void ShelfController::OnTabletModeStarted() {
Sammie Quon40cdcc1a2017-09-21 22:25:49328 // Force the shelf to be visible and to be bottom aligned in tablet mode; the
329 // prefs are restored on exit.
Qiang Xub7127da62017-08-29 01:44:57330 for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
331 Shelf* shelf = GetShelfForDisplay(display.id());
Sammie Quon40cdcc1a2017-09-21 22:25:49332 if (shelf) {
Sammie Quona87fc322017-11-10 17:43:37333 // Only animate into tablet mode if the shelf alignment will not change.
334 if (shelf->IsHorizontalAlignment())
335 shelf->set_is_tablet_mode_animation_running(true);
Qiang Xub7127da62017-08-29 01:44:57336 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
Sammie Quon40cdcc1a2017-09-21 22:25:49337 shelf->SetAlignment(SHELF_ALIGNMENT_BOTTOM);
338 }
Qiang Xub7127da62017-08-29 01:44:57339 }
340}
341
342void ShelfController::OnTabletModeEnded() {
Sammie Quon40cdcc1a2017-09-21 22:25:49343 SetShelfBehaviorsFromPrefs();
Sammie Quona87fc322017-11-10 17:43:37344 // Only animate out of tablet mode if the shelf alignment will not change.
345 for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
346 Shelf* shelf = GetShelfForDisplay(display.id());
347 if (shelf && shelf->IsHorizontalAlignment())
348 shelf->set_is_tablet_mode_animation_running(true);
349 }
Qiang Xub7127da62017-08-29 01:44:57350}
351
Michael Wasserman39e4fe42017-08-08 23:49:42352void ShelfController::OnDisplayConfigurationChanged() {
353 // Set/init the shelf behaviors from preferences, in case a display was added.
354 SetShelfBehaviorsFromPrefs();
355}
356
357void ShelfController::OnWindowTreeHostReusedForDisplay(
358 AshWindowTreeHost* window_tree_host,
359 const display::Display& display) {
360 // See comment in OnWindowTreeHostsSwappedDisplays().
361 SetShelfBehaviorsFromPrefs();
362}
363
364void ShelfController::OnWindowTreeHostsSwappedDisplays(
365 AshWindowTreeHost* host1,
366 AshWindowTreeHost* host2) {
367 // The display ids for existing shelf instances may have changed, so update
368 // the alignment and auto-hide state from prefs. See http://crbug.com/748291
369 SetShelfBehaviorsFromPrefs();
370}
371
Alex Newcomerd929ca162018-01-18 23:24:47372void ShelfController::OnNotificationAdded(const std::string& notification_id) {
373 if (!is_touchable_app_context_menu_enabled_)
374 return;
375
376 message_center::Notification* notification =
377 message_center::MessageCenter::Get()->FindVisibleNotificationById(
378 notification_id);
Alex Newcomer9d92fcb92018-01-24 18:37:53379
Alex Newcomera3bcc9b2018-03-02 18:06:08380 if (!notification)
381 return;
382
383 // Skip this if the notification shouldn't badge an app.
384 if (notification->notifier_id().type !=
385 message_center::NotifierId::APPLICATION &&
386 notification->notifier_id().type !=
387 message_center::NotifierId::ARC_APPLICATION) {
Alex Newcomerd929ca162018-01-18 23:24:47388 return;
Alex Newcomer509bf672018-02-08 00:03:30389 }
Alex Newcomerd929ca162018-01-18 23:24:47390
Alex Newcomera3bcc9b2018-03-02 18:06:08391 // Skip this if the notification doesn't have a valid app id.
392 if (notification->notifier_id().id == ash::kDefaultArcNotifierId)
393 return;
394
Alex Newcomerd929ca162018-01-18 23:24:47395 model_.AddNotificationRecord(notification->notifier_id().id, notification_id);
396}
397
398void ShelfController::OnNotificationRemoved(const std::string& notification_id,
399 bool by_user) {
400 if (!is_touchable_app_context_menu_enabled_)
401 return;
402
403 model_.RemoveNotificationRecord(notification_id);
404}
405
James Cookb0bf8e82017-04-09 17:01:44406} // namespace ash