cros: Add Notification indicators for shelf app icons

This CL includes:
- New feature flag (omitting the chrome://flags for now per pm request)
- Added functionality to Shelf MVC with tests.
- Added new state to ShelfButton.
- Added new field to ShelfItem.

Flow:
- ShelfController now observes MessageCenter.
- ShelfController sends the Notification ID to the ShelfModel.
- ShelfModel updates the appropriate ShelfItem.
- ShelfView::OnShelfItemChanged handles updating the icons indicator.

About the two new maps in ShelfModel:
- We need the NotificationId->AppId map because when the Notification is
  deleted, we lose the ability to look up the Notification's AppId.
- We need the AppId->NotificationId map so an app can look-up all of
  its notifications.

Bug: 801014
Change-Id: Ic4ad751bbff97b3c9dc96e5af5421f6979cec933
Reviewed-on: https://chromium-review.googlesource.com/862167
Reviewed-by: Xiyuan Xia <[email protected]>
Reviewed-by: Scott Violet <[email protected]>
Reviewed-by: Michael Wasserman <[email protected]>
Commit-Queue: Alex Newcomer <[email protected]>
Cr-Commit-Position: refs/heads/master@{#530331}
diff --git a/ash/shelf/shelf_controller.cc b/ash/shelf/shelf_controller.cc
index d08afcc..55c8c327 100644
--- a/ash/shelf/shelf_controller.cc
+++ b/ash/shelf/shelf_controller.cc
@@ -25,10 +25,12 @@
 #include "components/prefs/pref_change_registrar.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
+#include "ui/app_list/app_list_features.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/models/simple_menu_model.h"
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
+#include "ui/message_center/message_center.h"
 
 namespace ash {
 
@@ -97,7 +99,10 @@
 
 }  // namespace
 
-ShelfController::ShelfController() {
+ShelfController::ShelfController()
+    : is_touchable_app_context_menu_enabled_(
+          app_list::features::IsTouchableAppContextMenuEnabled()),
+      message_center_observer_(this) {
   // Synchronization is required in the Mash config, since Chrome and Ash run in
   // separate processes; it's optional via kAshDisableShelfModelSynchronization
   // in the Classic Ash config, where Chrome can uses Ash's ShelfModel directly.
@@ -126,6 +131,8 @@
   Shell::Get()->session_controller()->AddObserver(this);
   Shell::Get()->tablet_mode_controller()->AddObserver(this);
   Shell::Get()->window_tree_host_manager()->AddObserver(this);
+  if (is_touchable_app_context_menu_enabled_)
+    message_center_observer_.Add(message_center::MessageCenter::Get());
 }
 
 ShelfController::~ShelfController() {
@@ -376,4 +383,28 @@
   SetShelfBehaviorsFromPrefs();
 }
 
+void ShelfController::OnNotificationAdded(const std::string& notification_id) {
+  if (!is_touchable_app_context_menu_enabled_)
+    return;
+
+  message_center::Notification* notification =
+      message_center::MessageCenter::Get()->FindVisibleNotificationById(
+          notification_id);
+  // If the notification is for an ARC app, return early.
+  // TODO(newcomer): Support ARC app notifications.
+  if (notification->notifier_id().type !=
+      message_center::NotifierId::APPLICATION)
+    return;
+
+  model_.AddNotificationRecord(notification->notifier_id().id, notification_id);
+}
+
+void ShelfController::OnNotificationRemoved(const std::string& notification_id,
+                                            bool by_user) {
+  if (!is_touchable_app_context_menu_enabled_)
+    return;
+
+  model_.RemoveNotificationRecord(notification_id);
+}
+
 }  // namespace ash