Add notification dots and popup menu notification support to the taskbar.
- Added support for notification dots
- Added support for notifications in popup menu
- Added support for dismissing notifications from the popup menu
Bug: 198438631
Test: long pressed launcher and taskbar icons, clicked notifications, clicked shortcuts
Change-Id: I7c981e60a82b4d6ce28332d804bbbfb5eb89c6a8
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 8154168..0656125 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -669,6 +669,8 @@
return !isWorkspaceLoading();
}
+ @NonNull
+ @Override
public PopupDataProvider getPopupDataProvider() {
return mPopupDataProvider;
}
@@ -948,7 +950,7 @@
hideKeyboard();
logStopAndResume(false /* isResume */);
mAppWidgetHost.setActivityStarted(false);
- NotificationListener.removeNotificationsChangedListener();
+ NotificationListener.removeNotificationsChangedListener(getPopupDataProvider());
}
@Override
@@ -977,7 +979,7 @@
mModel.validateModelDataOnResume();
// Set the notification listener and fetch updated notifications when we resume
- NotificationListener.setNotificationsChangedListener(mPopupDataProvider);
+ NotificationListener.addNotificationsChangedListener(mPopupDataProvider);
DiscoveryBounce.showForHomeIfNeeded(this);
mAppWidgetHost.setActivityResumed(true);
diff --git a/src/com/android/launcher3/notification/NotificationInfo.java b/src/com/android/launcher3/notification/NotificationInfo.java
index d27d8c7..ebe45a5 100644
--- a/src/com/android/launcher3/notification/NotificationInfo.java
+++ b/src/com/android/launcher3/notification/NotificationInfo.java
@@ -29,12 +29,13 @@
import android.view.View;
import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.dot.DotInfo;
import com.android.launcher3.graphics.IconPalette;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.views.ActivityContext;
/**
* An object that contains relevant information from a {@link StatusBarNotification}. This should
@@ -99,21 +100,23 @@
if (intent == null) {
return;
}
- final Launcher launcher = Launcher.getLauncher(view.getContext());
+ final ActivityContext context = ActivityContext.lookupContext(view.getContext());
Bundle activityOptions = ActivityOptions.makeClipRevealAnimation(
view, 0, 0, view.getWidth(), view.getHeight()).toBundle();
try {
intent.send(null, 0, null, null, null, null, activityOptions);
- launcher.getStatsLogManager().logger().withItemInfo(mItemInfo)
+ context.getStatsLogManager().logger().withItemInfo(mItemInfo)
.log(LAUNCHER_NOTIFICATION_LAUNCH_TAP);
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
if (autoCancel) {
- launcher.getPopupDataProvider().cancelNotification(notificationKey);
+ PopupDataProvider popupDataProvider = context.getPopupDataProvider();
+ if (popupDataProvider != null) {
+ popupDataProvider.cancelNotification(notificationKey);
+ }
}
- AbstractFloatingView.closeOpenContainer(launcher, AbstractFloatingView
- .TYPE_ACTION_POPUP);
+ AbstractFloatingView.closeOpenContainer(context, AbstractFloatingView.TYPE_ACTION_POPUP);
}
public Drawable getIconForBackground(Context context, int background) {
diff --git a/src/com/android/launcher3/notification/NotificationListener.java b/src/com/android/launcher3/notification/NotificationListener.java
index e58f5fa..bbeb886 100644
--- a/src/com/android/launcher3/notification/NotificationListener.java
+++ b/src/com/android/launcher3/notification/NotificationListener.java
@@ -30,6 +30,7 @@
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
+import android.util.ArraySet;
import android.util.Log;
import android.util.Pair;
@@ -66,7 +67,8 @@
private static final int MSG_RANKING_UPDATE = 5;
private static NotificationListener sNotificationListenerInstance = null;
- private static NotificationsChangedListener sNotificationsChangedListener;
+ private static final ArraySet<NotificationsChangedListener> sNotificationsChangedListeners =
+ new ArraySet<>();
private static boolean sIsConnected;
private final Handler mWorkerHandler;
@@ -94,8 +96,11 @@
return sIsConnected ? sNotificationListenerInstance : null;
}
- public static void setNotificationsChangedListener(NotificationsChangedListener listener) {
- sNotificationsChangedListener = listener;
+ public static void addNotificationsChangedListener(NotificationsChangedListener listener) {
+ if (listener == null) {
+ return;
+ }
+ sNotificationsChangedListeners.add(listener);
NotificationListener notificationListener = getInstanceIfConnected();
if (notificationListener != null) {
@@ -108,8 +113,10 @@
}
}
- public static void removeNotificationsChangedListener() {
- sNotificationsChangedListener = null;
+ public static void removeNotificationsChangedListener(NotificationsChangedListener listener) {
+ if (listener != null) {
+ sNotificationsChangedListeners.remove(listener);
+ }
}
private boolean handleWorkerMessage(Message message) {
@@ -180,23 +187,27 @@
private boolean handleUiMessage(Message message) {
switch (message.what) {
case MSG_NOTIFICATION_POSTED:
- if (sNotificationsChangedListener != null) {
+ if (sNotificationsChangedListeners.size() > 0) {
Pair<PackageUserKey, NotificationKeyData> msg = (Pair) message.obj;
- sNotificationsChangedListener.onNotificationPosted(
- msg.first, msg.second);
+ for (NotificationsChangedListener listener : sNotificationsChangedListeners) {
+ listener.onNotificationPosted(msg.first, msg.second);
+ }
}
break;
case MSG_NOTIFICATION_REMOVED:
- if (sNotificationsChangedListener != null) {
+ if (sNotificationsChangedListeners.size() > 0) {
Pair<PackageUserKey, NotificationKeyData> msg = (Pair) message.obj;
- sNotificationsChangedListener.onNotificationRemoved(
- msg.first, msg.second);
+ for (NotificationsChangedListener listener : sNotificationsChangedListeners) {
+ listener.onNotificationRemoved(msg.first, msg.second);
+ }
}
break;
case MSG_NOTIFICATION_FULL_REFRESH:
- if (sNotificationsChangedListener != null) {
- sNotificationsChangedListener.onNotificationFullRefresh(
- (List<StatusBarNotification>) message.obj);
+ if (sNotificationsChangedListeners.size() > 0) {
+ for (NotificationsChangedListener listener : sNotificationsChangedListeners) {
+ listener.onNotificationFullRefresh(
+ (List<StatusBarNotification>) message.obj);
+ }
}
break;
}
diff --git a/src/com/android/launcher3/notification/NotificationMainView.java b/src/com/android/launcher3/notification/NotificationMainView.java
index f9ff8a6..16a4057 100644
--- a/src/com/android/launcher3/notification/NotificationMainView.java
+++ b/src/com/android/launcher3/notification/NotificationMainView.java
@@ -38,11 +38,12 @@
import androidx.annotation.Nullable;
-import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.util.Themes;
+import com.android.launcher3.views.ActivityContext;
/**
* A {@link android.widget.FrameLayout} that contains a single notification,
@@ -320,9 +321,12 @@
}
public void onChildDismissed() {
- Launcher launcher = Launcher.getLauncher(getContext());
- launcher.getPopupDataProvider().cancelNotification(
- mNotificationInfo.notificationKey);
- launcher.getStatsLogManager().logger().log(LAUNCHER_NOTIFICATION_DISMISSED);
+ ActivityContext activityContext = ActivityContext.lookupContext(getContext());
+ PopupDataProvider popupDataProvider = activityContext.getPopupDataProvider();
+ if (popupDataProvider == null) {
+ return;
+ }
+ popupDataProvider.cancelNotification(mNotificationInfo.notificationKey);
+ activityContext.getStatsLogManager().logger().log(LAUNCHER_NOTIFICATION_DISMISSED);
}
}
diff --git a/src/com/android/launcher3/popup/LauncherPopupLiveUpdateHandler.java b/src/com/android/launcher3/popup/LauncherPopupLiveUpdateHandler.java
new file mode 100644
index 0000000..731f439
--- /dev/null
+++ b/src/com/android/launcher3/popup/LauncherPopupLiveUpdateHandler.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2021 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.view.View;
+import android.view.ViewGroup;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.model.data.ItemInfo;
+
+/**
+ * Utility class to handle updates while the popup is visible on the Launcher
+ */
+public class LauncherPopupLiveUpdateHandler extends PopupLiveUpdateHandler<Launcher> {
+
+ public LauncherPopupLiveUpdateHandler(
+ Launcher launcher, PopupContainerWithArrow<Launcher> popupContainerWithArrow) {
+ super(launcher, popupContainerWithArrow);
+ }
+
+ private View getWidgetsView(ViewGroup container) {
+ for (int i = container.getChildCount() - 1; i >= 0; --i) {
+ View systemShortcutView = container.getChildAt(i);
+ if (systemShortcutView.getTag() instanceof SystemShortcut.Widgets) {
+ return systemShortcutView;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void onWidgetsBound() {
+ ItemInfo itemInfo = (ItemInfo) mPopupContainerWithArrow.getOriginalIcon().getTag();
+ SystemShortcut widgetInfo = SystemShortcut.WIDGETS.getShortcut(mContext, itemInfo);
+ View widgetsView = getWidgetsView(mPopupContainerWithArrow);
+ if (widgetsView == null && mPopupContainerWithArrow.getWidgetContainer() != null) {
+ widgetsView = getWidgetsView(mPopupContainerWithArrow.getWidgetContainer());
+ }
+
+ if (widgetInfo != null && widgetsView == null) {
+ // We didn't have any widgets cached but now there are some, so enable the shortcut.
+ if (mPopupContainerWithArrow.getSystemShortcutContainer()
+ != mPopupContainerWithArrow) {
+ if (mPopupContainerWithArrow.getWidgetContainer() == null) {
+ mPopupContainerWithArrow.setWidgetContainer(
+ mPopupContainerWithArrow.inflateAndAdd(
+ R.layout.widget_shortcut_container,
+ mPopupContainerWithArrow));
+ }
+ mPopupContainerWithArrow.initializeSystemShortcut(
+ R.layout.system_shortcut,
+ mPopupContainerWithArrow.getWidgetContainer(),
+ widgetInfo);
+ } else {
+ // If using the expanded system shortcut (as opposed to just the icon), we need
+ // to reopen the container to ensure measurements etc. all work out. While this
+ // could be quite janky, in practice the user would typically see a small
+ // flicker as the animation restarts partway through, and this is a very rare
+ // edge case anyway.
+ mPopupContainerWithArrow.close(false);
+ PopupContainerWithArrow.showForIcon(mPopupContainerWithArrow.getOriginalIcon());
+ }
+ } else if (widgetInfo == null && widgetsView != null) {
+ // No widgets exist, but we previously added the shortcut so remove it.
+ if (mPopupContainerWithArrow.getSystemShortcutContainer()
+ != mPopupContainerWithArrow
+ && mPopupContainerWithArrow.getWidgetContainer() != null) {
+ mPopupContainerWithArrow.getWidgetContainer().removeView(widgetsView);
+ } else {
+ mPopupContainerWithArrow.close(false);
+ PopupContainerWithArrow.showForIcon(mPopupContainerWithArrow.getOriginalIcon());
+ }
+ }
+ }
+}
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 278f57d..aa8c70b 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -60,7 +60,6 @@
import com.android.launcher3.notification.NotificationContainer;
import com.android.launcher3.notification.NotificationInfo;
import com.android.launcher3.notification.NotificationKeyData;
-import com.android.launcher3.popup.PopupDataProvider.PopupDataChangeListener;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
import com.android.launcher3.touch.ItemLongClickListener;
@@ -72,9 +71,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
-import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
@@ -225,7 +222,8 @@
}
private void configureForLauncher(Launcher launcher) {
- addOnAttachStateChangeListener(new LiveUpdateHandler(launcher));
+ addOnAttachStateChangeListener(new LauncherPopupLiveUpdateHandler(
+ launcher, (PopupContainerWithArrow<Launcher>) this));
mPopupItemDragHandler = new LauncherPopupItemDragHandler(launcher, this);
mAccessibilityDelegate = new ShortcutMenuAccessibilityDelegate(launcher);
launcher.getDragController().addDragListener(this);
@@ -329,6 +327,26 @@
this, mShortcuts, notificationKeys));
}
+ protected NotificationContainer getNotificationContainer() {
+ return mNotificationContainer;
+ }
+
+ protected BubbleTextView getOriginalIcon() {
+ return mOriginalIcon;
+ }
+
+ protected ViewGroup getSystemShortcutContainer() {
+ return mSystemShortcutContainer;
+ }
+
+ protected ViewGroup getWidgetContainer() {
+ return mWidgetContainer;
+ }
+
+ protected void setWidgetContainer(ViewGroup widgetContainer) {
+ mWidgetContainer = widgetContainer;
+ }
+
private String getTitleForAccessibility() {
return getContext().getString(mNumNotifications == 0 ?
R.string.action_deep_shortcut :
@@ -352,7 +370,7 @@
}
}
- private void updateHiddenShortcuts() {
+ protected void updateHiddenShortcuts() {
int allowedCount = mNotificationContainer != null
? MAX_SHORTCUTS_IF_NOTIFICATIONS : MAX_SHORTCUTS;
@@ -363,7 +381,7 @@
}
}
- private void initializeSystemShortcut(int resId, ViewGroup container, SystemShortcut info) {
+ protected void initializeSystemShortcut(int resId, ViewGroup container, SystemShortcut info) {
View view = inflateAndAdd(
resId, container, getInsertIndexForSystemShortcut(container, info));
if (view instanceof DeepShortcutView) {
@@ -436,7 +454,7 @@
};
}
- private void updateNotificationHeader() {
+ protected void updateNotificationHeader() {
ItemInfoWithIcon itemInfo = (ItemInfoWithIcon) mOriginalIcon.getTag();
DotInfo dotInfo = mActivityContext.getDotInfoForItem(itemInfo);
if (mNotificationContainer != null && dotInfo != null) {
@@ -495,118 +513,6 @@
}
/**
- * Utility class to handle updates while the popup is visible (like widgets and
- * notification changes)
- */
- private class LiveUpdateHandler implements
- PopupDataChangeListener, View.OnAttachStateChangeListener {
-
- private final Launcher mLauncher;
-
- LiveUpdateHandler(Launcher launcher) {
- mLauncher = launcher;
- }
-
- @Override
- public void onViewAttachedToWindow(View view) {
- mLauncher.getPopupDataProvider().setChangeListener(this);
- }
-
- @Override
- public void onViewDetachedFromWindow(View view) {
- mLauncher.getPopupDataProvider().setChangeListener(null);
- }
-
- private View getWidgetsView(ViewGroup container) {
- for (int i = container.getChildCount() - 1; i >= 0; --i) {
- View systemShortcutView = container.getChildAt(i);
- if (systemShortcutView.getTag() instanceof SystemShortcut.Widgets) {
- return systemShortcutView;
- }
- }
- return null;
- }
-
- @Override
- public void onWidgetsBound() {
- ItemInfo itemInfo = (ItemInfo) mOriginalIcon.getTag();
- SystemShortcut widgetInfo = SystemShortcut.WIDGETS.getShortcut(mLauncher, itemInfo);
- View widgetsView = getWidgetsView(PopupContainerWithArrow.this);
- if (widgetsView == null && mWidgetContainer != null) {
- widgetsView = getWidgetsView(mWidgetContainer);
- }
-
- if (widgetInfo != null && widgetsView == null) {
- // We didn't have any widgets cached but now there are some, so enable the shortcut.
- if (mSystemShortcutContainer != PopupContainerWithArrow.this) {
- if (mWidgetContainer == null) {
- mWidgetContainer = inflateAndAdd(R.layout.widget_shortcut_container,
- PopupContainerWithArrow.this);
- }
- initializeSystemShortcut(R.layout.system_shortcut, mWidgetContainer,
- widgetInfo);
- } else {
- // If using the expanded system shortcut (as opposed to just the icon), we need
- // to reopen the container to ensure measurements etc. all work out. While this
- // could be quite janky, in practice the user would typically see a small
- // flicker as the animation restarts partway through, and this is a very rare
- // edge case anyway.
- close(false);
- PopupContainerWithArrow.showForIcon(mOriginalIcon);
- }
- } else if (widgetInfo == null && widgetsView != null) {
- // No widgets exist, but we previously added the shortcut so remove it.
- if (mSystemShortcutContainer
- != PopupContainerWithArrow.this
- && mWidgetContainer != null) {
- mWidgetContainer.removeView(widgetsView);
- } else {
- close(false);
- PopupContainerWithArrow.showForIcon(mOriginalIcon);
- }
- }
- }
-
- /**
- * Updates the notification header if the original icon's dot updated.
- */
- @Override
- public void onNotificationDotsUpdated(Predicate<PackageUserKey> updatedDots) {
- ItemInfo itemInfo = (ItemInfo) mOriginalIcon.getTag();
- PackageUserKey packageUser = PackageUserKey.fromItemInfo(itemInfo);
- if (updatedDots.test(packageUser)) {
- updateNotificationHeader();
- }
- }
-
-
- @Override
- public void trimNotifications(Map<PackageUserKey, DotInfo> updatedDots) {
- if (mNotificationContainer == null) {
- return;
- }
- ItemInfo originalInfo = (ItemInfo) mOriginalIcon.getTag();
- DotInfo dotInfo = updatedDots.get(PackageUserKey.fromItemInfo(originalInfo));
- if (dotInfo == null || dotInfo.getNotificationKeys().size() == 0) {
- // No more notifications, remove the notification views and expand all shortcuts.
- mNotificationContainer.setVisibility(GONE);
- updateHiddenShortcuts();
- assignMarginsAndBackgrounds(PopupContainerWithArrow.this);
- updateArrowColor();
- } else {
- mNotificationContainer.trimNotifications(
- NotificationKeyData.extractKeysOnly(dotInfo.getNotificationKeys()));
- }
- }
-
- @Override
- public void onSystemShortcutsUpdated() {
- close(true);
- PopupContainerWithArrow.showForIcon(mOriginalIcon);
- }
- }
-
- /**
* Dismisses the popup if it is no longer valid
*/
public static void dismissInvalidPopup(BaseDraggingActivity activity) {
diff --git a/src/com/android/launcher3/popup/PopupLiveUpdateHandler.java b/src/com/android/launcher3/popup/PopupLiveUpdateHandler.java
new file mode 100644
index 0000000..194c22f
--- /dev/null
+++ b/src/com/android/launcher3/popup/PopupLiveUpdateHandler.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2021 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 static android.view.View.GONE;
+
+import android.content.Context;
+import android.view.View;
+
+import com.android.launcher3.dot.DotInfo;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.notification.NotificationContainer;
+import com.android.launcher3.notification.NotificationKeyData;
+import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.views.ActivityContext;
+
+import java.util.Map;
+import java.util.function.Predicate;
+
+/**
+ * Utility class to handle updates while the popup is visible (like widgets and
+ * notification changes)
+ *
+ * @param <T> The activity on which the popup shows
+ */
+public class PopupLiveUpdateHandler<T extends Context & ActivityContext> implements
+ PopupDataProvider.PopupDataChangeListener, View.OnAttachStateChangeListener {
+
+ protected final T mContext;
+ protected final PopupContainerWithArrow<T> mPopupContainerWithArrow;
+
+ public PopupLiveUpdateHandler(
+ T context, PopupContainerWithArrow<T> popupContainerWithArrow) {
+ mContext = context;
+ mPopupContainerWithArrow = popupContainerWithArrow;
+ }
+
+ @Override
+ public void onViewAttachedToWindow(View view) {
+ PopupDataProvider popupDataProvider = mContext.getPopupDataProvider();
+
+ if (popupDataProvider != null) {
+ popupDataProvider.setChangeListener(this);
+ }
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View view) {
+ PopupDataProvider popupDataProvider = mContext.getPopupDataProvider();
+
+ if (popupDataProvider != null) {
+ popupDataProvider.setChangeListener(null);
+ }
+ }
+
+ /**
+ * Updates the notification header if the original icon's dot updated.
+ */
+ @Override
+ public void onNotificationDotsUpdated(Predicate<PackageUserKey> updatedDots) {
+ ItemInfo itemInfo = (ItemInfo) mPopupContainerWithArrow.getOriginalIcon().getTag();
+ PackageUserKey packageUser = PackageUserKey.fromItemInfo(itemInfo);
+ if (updatedDots.test(packageUser)) {
+ mPopupContainerWithArrow.updateNotificationHeader();
+ }
+ }
+
+
+ @Override
+ public void trimNotifications(Map<PackageUserKey, DotInfo> updatedDots) {
+ NotificationContainer notificationContainer =
+ mPopupContainerWithArrow.getNotificationContainer();
+ if (notificationContainer == null) {
+ return;
+ }
+ ItemInfo originalInfo = (ItemInfo) mPopupContainerWithArrow.getOriginalIcon().getTag();
+ DotInfo dotInfo = updatedDots.get(PackageUserKey.fromItemInfo(originalInfo));
+ if (dotInfo == null || dotInfo.getNotificationKeys().size() == 0) {
+ // No more notifications, remove the notification views and expand all shortcuts.
+ notificationContainer.setVisibility(GONE);
+ mPopupContainerWithArrow.updateHiddenShortcuts();
+ mPopupContainerWithArrow.assignMarginsAndBackgrounds(mPopupContainerWithArrow);
+ mPopupContainerWithArrow.updateArrowColor();
+ } else {
+ notificationContainer.trimNotifications(
+ NotificationKeyData.extractKeysOnly(dotInfo.getNotificationKeys()));
+ }
+ }
+
+ @Override
+ public void onSystemShortcutsUpdated() {
+ mPopupContainerWithArrow.close(true);
+ PopupContainerWithArrow.showForIcon(mPopupContainerWithArrow.getOriginalIcon());
+ }
+}
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
index 1820933..0d8602f 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
@@ -33,6 +33,7 @@
import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.popup.PopupContainerWithArrow;
+import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.util.ShortcutUtil;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.BaseDragLayer;
@@ -177,12 +178,16 @@
if (!ShortcutUtil.supportsShortcuts(item)) {
return false;
}
+ PopupDataProvider popupDataProvider = mActivity.getPopupDataProvider();
+ if (popupDataProvider == null) {
+ return false;
+ }
final PopupContainerWithArrow container =
(PopupContainerWithArrow) mActivity.getLayoutInflater().inflate(
R.layout.popup_container, mActivity.getDragLayer(), false);
container.populateAndShow((BubbleTextView) v,
- mActivity.getPopupDataProvider().getShortcutCountForItem(item),
+ popupDataProvider.getShortcutCountForItem(item),
Collections.emptyList(),
Arrays.asList(mPinnedAppsAdapter.getSystemShortcut(item),
APP_INFO.getShortcut(mActivity, item)));
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index a2e4ad6..e09eff6 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -31,6 +31,7 @@
import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.util.ViewCache;
/**
@@ -166,4 +167,9 @@
// No op.
};
}
+
+ @Nullable
+ default PopupDataProvider getPopupDataProvider() {
+ return null;
+ }
}