summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/popup/PopupDataProvider.java
diff options
context:
space:
mode:
authorTony Wickham <twickham@google.com>2017-01-20 08:15:28 -0800
committerTony Wickham <twickham@google.com>2017-01-25 09:51:06 -0800
commit010d2550184179785e4467ff1ffb4f4f4e850ec2 (patch)
tree533ad5bc79d26b10fda6a4ab7a88f5d43643c4ea /src/com/android/launcher3/popup/PopupDataProvider.java
parentc711e6006f380a500a48383b4f079258b47d4a0d (diff)
downloadandroid_packages_apps_Trebuchet-010d2550184179785e4467ff1ffb4f4f4e850ec2.tar.gz
android_packages_apps_Trebuchet-010d2550184179785e4467ff1ffb4f4f4e850ec2.tar.bz2
android_packages_apps_Trebuchet-010d2550184179785e4467ff1ffb4f4f4e850ec2.zip
Add NotificationListener to launcher.
- NotificationListener extends NotificationListenerService, and is added to the manifest. - Added PopupDataProvider, which contains logic for storing and interacting with data that goes into the long-press popup menu (shortcuts and notifications). A follow-up CL will rename DeepShortcutsContainer to a generic PopupContainerWithArrow. - If Launcher has notification access, NotificationListener will get callbacks when notifications are posted and removed; upon receiving these callbacks, NotificationListener passes them to PopupDataProvider via a NotificationsChangedListener interface. - Upon receiving the changed notifications, PopupDataProvider maps them to the corresponding package/user and tells launcher to update relevant icons on the workspace and all apps. This is guarded by FeatureFlags.BADGE_ICONS. Bug: 32410600 Change-Id: I59aeb31a7f92399c9c4b831ab551e51e13f44f5c
Diffstat (limited to 'src/com/android/launcher3/popup/PopupDataProvider.java')
-rw-r--r--src/com/android/launcher3/popup/PopupDataProvider.java161
1 files changed, 161 insertions, 0 deletions
diff --git a/src/com/android/launcher3/popup/PopupDataProvider.java b/src/com/android/launcher3/popup/PopupDataProvider.java
new file mode 100644
index 000000000..4ed32b543
--- /dev/null
+++ b/src/com/android/launcher3/popup/PopupDataProvider.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.popup;
+
+import android.content.ComponentName;
+import android.service.notification.StatusBarNotification;
+import android.util.Log;
+
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.badge.BadgeInfo;
+import com.android.launcher3.badging.NotificationListener;
+import com.android.launcher3.shortcuts.DeepShortcutManager;
+import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.MultiHashMap;
+import com.android.launcher3.util.PackageUserKey;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Provides data for the popup menu that appears after long-clicking on apps.
+ */
+public class PopupDataProvider implements NotificationListener.NotificationsChangedListener {
+
+ private static final boolean LOGD = false;
+ private static final String TAG = "PopupDataProvider";
+
+ private final Launcher mLauncher;
+
+ /** Maps launcher activity components to their list of shortcut ids. */
+ private MultiHashMap<ComponentKey, String> mDeepShortcutMap = new MultiHashMap<>();
+ /** Maps packages to their BadgeInfo's . */
+ private Map<PackageUserKey, BadgeInfo> mPackageUserToBadgeInfos = new HashMap<>();
+
+ public PopupDataProvider(Launcher launcher) {
+ mLauncher = launcher;
+ }
+
+ @Override
+ public void onNotificationPosted(PackageUserKey postedPackageUserKey, String notificationKey) {
+ BadgeInfo oldBadgeInfo = mPackageUserToBadgeInfos.get(postedPackageUserKey);
+ if (oldBadgeInfo == null) {
+ BadgeInfo newBadgeInfo = new BadgeInfo(postedPackageUserKey);
+ newBadgeInfo.addNotificationKey(notificationKey);
+ mPackageUserToBadgeInfos.put(postedPackageUserKey, newBadgeInfo);
+ mLauncher.updateIconBadges(Collections.singleton(postedPackageUserKey));
+ } else if (oldBadgeInfo.addNotificationKey(notificationKey)) {
+ mLauncher.updateIconBadges(Collections.singleton(postedPackageUserKey));
+ }
+ }
+
+ @Override
+ public void onNotificationRemoved(PackageUserKey removedPackageUserKey, String notificationKey) {
+ BadgeInfo oldBadgeInfo = mPackageUserToBadgeInfos.get(removedPackageUserKey);
+ if (oldBadgeInfo != null && oldBadgeInfo.removeNotificationKey(notificationKey)) {
+ if (oldBadgeInfo.getNotificationCount() == 0) {
+ mPackageUserToBadgeInfos.remove(removedPackageUserKey);
+ }
+ mLauncher.updateIconBadges(Collections.singleton(removedPackageUserKey));
+ }
+ }
+
+ @Override
+ public void onNotificationFullRefresh(List<StatusBarNotification> activeNotifications) {
+ if (activeNotifications == null) return;
+ // This will contain the PackageUserKeys which have updated badges.
+ HashMap<PackageUserKey, BadgeInfo> updatedBadges = new HashMap<>(mPackageUserToBadgeInfos);
+ mPackageUserToBadgeInfos.clear();
+ for (StatusBarNotification notification : activeNotifications) {
+ PackageUserKey packageUserKey = PackageUserKey.fromNotification(notification);
+ BadgeInfo badgeInfo = mPackageUserToBadgeInfos.get(packageUserKey);
+ if (badgeInfo == null) {
+ badgeInfo = new BadgeInfo(packageUserKey);
+ mPackageUserToBadgeInfos.put(packageUserKey, badgeInfo);
+ }
+ badgeInfo.addNotificationKey(notification.getKey());
+ }
+
+ // Add and remove from updatedBadges so it contains the PackageUserKeys of updated badges.
+ for (PackageUserKey packageUserKey : mPackageUserToBadgeInfos.keySet()) {
+ BadgeInfo prevBadge = updatedBadges.get(packageUserKey);
+ BadgeInfo newBadge = mPackageUserToBadgeInfos.get(packageUserKey);
+ if (prevBadge == null) {
+ updatedBadges.put(packageUserKey, newBadge);
+ } else {
+ if (!prevBadge.shouldBeInvalidated(newBadge)) {
+ updatedBadges.remove(packageUserKey);
+ }
+ }
+ }
+
+ if (!updatedBadges.isEmpty()) {
+ mLauncher.updateIconBadges(updatedBadges.keySet());
+ }
+ }
+
+ public void setDeepShortcutMap(MultiHashMap<ComponentKey, String> deepShortcutMapCopy) {
+ mDeepShortcutMap = deepShortcutMapCopy;
+ if (LOGD) Log.d(TAG, "bindDeepShortcutMap: " + mDeepShortcutMap);
+ }
+
+ public List<String> getShortcutIdsForItem(ItemInfo info) {
+ if (!DeepShortcutManager.supportsShortcuts(info)) {
+ return Collections.EMPTY_LIST;
+ }
+ ComponentName component = info.getTargetComponent();
+ if (component == null) {
+ return Collections.EMPTY_LIST;
+ }
+
+ List<String> ids = mDeepShortcutMap.get(new ComponentKey(component, info.user));
+ return ids == null ? Collections.EMPTY_LIST : ids;
+ }
+
+ public BadgeInfo getBadgeInfoForItem(ItemInfo info) {
+ if (!DeepShortcutManager.supportsShortcuts(info)) {
+ return null;
+ }
+
+ return mPackageUserToBadgeInfos.get(PackageUserKey.fromItemInfo(info));
+ }
+
+ public String[] getNotificationKeysForItem(ItemInfo info) {
+ BadgeInfo badgeInfo = mPackageUserToBadgeInfos.get(PackageUserKey.fromItemInfo(info));
+ Set<String> notificationKeys = badgeInfo.getNotificationKeys();
+ return notificationKeys.toArray(new String[notificationKeys.size()]);
+ }
+
+ /** This makes a potentially expensive binder call and should be run on a background thread. */
+ public List<StatusBarNotification> getStatusBarNotificationsForKeys(String[] notificationKeys) {
+ NotificationListener notificationListener = NotificationListener.getInstance();
+ return notificationListener == null ? Collections.EMPTY_LIST
+ : notificationListener.getNotificationsForKeys(notificationKeys);
+ }
+
+ public void cancelNotification(String notificationKey) {
+ NotificationListener notificationListener = NotificationListener.getInstance();
+ if (notificationListener == null) {
+ return;
+ }
+ notificationListener.cancelNotification(notificationKey);
+ }
+}