From 49a3e699f9c5dfbd220681c17037621751ffe933 Mon Sep 17 00:00:00 2001 From: Pinyao Ting Date: Fri, 26 Jul 2019 12:28:38 -0700 Subject: show dot in deep shortcuts when notification contains exactly identical set of person Bug: 132336512 Change-Id: I975524e28168c10a186cdc24b188c161faf433cf --- .../launcher3/shortcuts/DeepShortcutManager.java | 12 ----- .../android/launcher3/uioverrides/UiFactory.java | 7 +++ src/com/android/launcher3/Launcher.java | 3 +- src/com/android/launcher3/Utilities.java | 4 ++ src/com/android/launcher3/WorkspaceItemInfo.java | 23 +++++++++ .../LauncherAccessibilityDelegate.java | 3 +- .../notification/NotificationKeyData.java | 25 +++++++-- .../launcher3/popup/PopupContainerWithArrow.java | 3 +- .../android/launcher3/popup/PopupDataProvider.java | 22 +++++--- src/com/android/launcher3/util/PackageUserKey.java | 2 +- src/com/android/launcher3/util/ShortcutUtil.java | 59 ++++++++++++++++++++++ .../launcher3/shortcuts/DeepShortcutManager.java | 33 ------------ .../android/launcher3/uioverrides/UiFactory.java | 6 +++ 13 files changed, 144 insertions(+), 58 deletions(-) create mode 100644 src/com/android/launcher3/util/ShortcutUtil.java diff --git a/go/src/com/android/launcher3/shortcuts/DeepShortcutManager.java b/go/src/com/android/launcher3/shortcuts/DeepShortcutManager.java index 5fe350342..42b119429 100644 --- a/go/src/com/android/launcher3/shortcuts/DeepShortcutManager.java +++ b/go/src/com/android/launcher3/shortcuts/DeepShortcutManager.java @@ -45,18 +45,6 @@ public class DeepShortcutManager { private DeepShortcutManager() { } - public static boolean supportsShortcuts(ItemInfo info) { - return false; - } - - public static boolean supportsDeepShortcuts(ItemInfo info) { - return false; - } - - public static String getShortcutIdIfApplicable(ItemInfo info) { - return null; - } - /** * Queries for the shortcuts with the package name and provided ids. * diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java index 97cd38a11..c02df9386 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java +++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java @@ -32,9 +32,11 @@ import static com.android.launcher3.allapps.DiscoveryBounce.SHELF_BOUNCE_SEEN; import android.animation.AnimatorSet; import android.animation.ValueAnimator; import android.app.Activity; +import android.app.Person; import android.content.Context; import android.content.Intent; import android.content.IntentSender; +import android.content.pm.ShortcutInfo; import android.os.Bundle; import android.os.CancellationSignal; import android.util.Base64; @@ -244,4 +246,9 @@ public class UiFactory extends RecentsUiFactory { } return new ScaleAndTranslation(1.1f, 0f, 0f); } + + public static Person[] getPersons(ShortcutInfo si) { + Person[] persons = si.getPersons(); + return persons == null ? Utilities.EMPTY_PERSON_ARRAY : persons; + } } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 74a98633e..c262e1619 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -129,6 +129,7 @@ import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.PendingRequestArgs; import com.android.launcher3.util.RaceConditionTracker; +import com.android.launcher3.util.ShortcutUtil; import com.android.launcher3.util.SystemUiController; import com.android.launcher3.util.Themes; import com.android.launcher3.util.Thunk; @@ -2489,7 +2490,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, KeyEvent.KEYCODE_O, KeyEvent.META_CTRL_ON)); } if (currentFocus.getTag() instanceof ItemInfo - && DeepShortcutManager.supportsShortcuts((ItemInfo) currentFocus.getTag())) { + && ShortcutUtil.supportsShortcuts((ItemInfo) currentFocus.getTag())) { shortcutInfos.add(new KeyboardShortcutInfo( getString(R.string.shortcuts_menu_with_notifications_description), KeyEvent.KEYCODE_S, KeyEvent.META_CTRL_ON)); diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 80305228b..05336f2e7 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -21,6 +21,7 @@ import static com.android.launcher3.ItemInfoWithIcon.FLAG_ICON_BADGED; import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.app.ActivityManager; +import android.app.Person; import android.app.WallpaperManager; import android.content.BroadcastReceiver; import android.content.Context; @@ -97,6 +98,9 @@ public final class Utilities { private static final Matrix sMatrix = new Matrix(); private static final Matrix sInverseMatrix = new Matrix(); + public static final String[] EMPTY_STRING_ARRAY = new String[0]; + public static final Person[] EMPTY_PERSON_ARRAY = new Person[0]; + public static final boolean ATLEAST_Q = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q; public static final boolean ATLEAST_P = diff --git a/src/com/android/launcher3/WorkspaceItemInfo.java b/src/com/android/launcher3/WorkspaceItemInfo.java index 5a2373b99..b72866c26 100644 --- a/src/com/android/launcher3/WorkspaceItemInfo.java +++ b/src/com/android/launcher3/WorkspaceItemInfo.java @@ -16,17 +16,23 @@ package com.android.launcher3; +import android.app.Person; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ShortcutInfo; import android.text.TextUtils; +import androidx.annotation.NonNull; + import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.icons.IconCache; import com.android.launcher3.shortcuts.ShortcutKey; +import com.android.launcher3.uioverrides.UiFactory; import com.android.launcher3.util.ContentWriter; +import java.util.Arrays; + /** * Represents a launchable icon on the workspaces and in folders. */ @@ -82,11 +88,18 @@ public class WorkspaceItemInfo extends ItemInfoWithIcon { public int status; + /** + * A set of person's Id associated with the WorkspaceItemInfo, this is only used if the item + * represents a deep shortcut. + */ + @NonNull private String[] personKeys = Utilities.EMPTY_STRING_ARRAY; + /** * The installation progress [0-100] of the package that this shortcut represents. */ private int mInstallProgress; + public WorkspaceItemInfo() { itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; } @@ -98,6 +111,7 @@ public class WorkspaceItemInfo extends ItemInfoWithIcon { iconResource = info.iconResource; status = info.status; mInstallProgress = info.mInstallProgress; + personKeys = info.personKeys.clone(); } /** TODO: Remove this. It's only called by ApplicationInfo.makeWorkspaceItem. */ @@ -175,6 +189,10 @@ public class WorkspaceItemInfo extends ItemInfoWithIcon { runtimeStatusFlags |= FLAG_DISABLED_BY_PUBLISHER; } disabledMessage = shortcutInfo.getDisabledMessage(); + + Person[] persons = UiFactory.getPersons(shortcutInfo); + personKeys = persons.length == 0 ? Utilities.EMPTY_STRING_ARRAY + : Arrays.stream(persons).map(Person::getKey).sorted().toArray(String[]::new); } /** Returns the WorkspaceItemInfo id associated with the deep shortcut. */ @@ -183,6 +201,11 @@ public class WorkspaceItemInfo extends ItemInfoWithIcon { getIntent().getStringExtra(ShortcutKey.EXTRA_SHORTCUT_ID) : null; } + @NonNull + public String[] getPersonKeys() { + return personKeys; + } + @Override public ComponentName getTargetComponent() { ComponentName cn = super.getTargetComponent(); diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java index fd4df5247..0c1303b64 100644 --- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java +++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java @@ -40,6 +40,7 @@ import com.android.launcher3.popup.PopupContainerWithArrow; import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.touch.ItemLongClickListener; import com.android.launcher3.util.IntArray; +import com.android.launcher3.util.ShortcutUtil; import com.android.launcher3.util.Thunk; import com.android.launcher3.widget.LauncherAppWidgetHostView; @@ -115,7 +116,7 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme // If the request came from keyboard, do not add custom shortcuts as that is already // exposed as a direct shortcut - if (!fromKeyboard && DeepShortcutManager.supportsShortcuts(item)) { + if (!fromKeyboard && ShortcutUtil.supportsShortcuts(item)) { info.addAction(mActions.get(NotificationListener.getInstanceIfConnected() != null ? SHORTCUTS_AND_NOTIFICATIONS : DEEP_SHORTCUTS)); } diff --git a/src/com/android/launcher3/notification/NotificationKeyData.java b/src/com/android/launcher3/notification/NotificationKeyData.java index 5050457b9..bfa4ba9ab 100644 --- a/src/com/android/launcher3/notification/NotificationKeyData.java +++ b/src/com/android/launcher3/notification/NotificationKeyData.java @@ -17,12 +17,18 @@ package com.android.launcher3.notification; import android.app.Notification; +import android.app.Person; import android.service.notification.StatusBarNotification; +import com.android.launcher3.Utilities; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; /** * The key data associated with the notification, used to determine what to include @@ -34,19 +40,25 @@ public class NotificationKeyData { public final String notificationKey; public final String shortcutId; public int count; + @NonNull public final String[] personKeysFromNotification; - private NotificationKeyData(String notificationKey, String shortcutId, int count) { + private NotificationKeyData(String notificationKey, String shortcutId, int count, + String[] personKeysFromNotification) { this.notificationKey = notificationKey; this.shortcutId = shortcutId; this.count = Math.max(1, count); + this.personKeysFromNotification = personKeysFromNotification; } public static NotificationKeyData fromNotification(StatusBarNotification sbn) { Notification notif = sbn.getNotification(); - return new NotificationKeyData(sbn.getKey(), notif.getShortcutId(), notif.number); + return new NotificationKeyData(sbn.getKey(), notif.getShortcutId(), notif.number, + extractPersonKeyOnly(notif.extras.getParcelableArrayList( + Notification.EXTRA_PEOPLE_LIST))); } - public static List extractKeysOnly(@NonNull List notificationKeys) { + public static List extractKeysOnly( + @NonNull List notificationKeys) { List keysOnly = new ArrayList<>(notificationKeys.size()); for (NotificationKeyData notificationKeyData : notificationKeys) { keysOnly.add(notificationKeyData.notificationKey); @@ -54,6 +66,13 @@ public class NotificationKeyData { return keysOnly; } + private static String[] extractPersonKeyOnly(@Nullable ArrayList people) { + if (people == null || people.isEmpty()) { + return Utilities.EMPTY_STRING_ARRAY; + } + return people.stream().map(Person::getKey).sorted().toArray(String[]::new); + } + @Override public boolean equals(Object obj) { if (!(obj instanceof NotificationKeyData)) { diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index 25d9f7976..baaad6573 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -72,6 +72,7 @@ import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.touch.ItemClickHandler; import com.android.launcher3.touch.ItemLongClickListener; import com.android.launcher3.util.PackageUserKey; +import com.android.launcher3.util.ShortcutUtil; import com.android.launcher3.views.BaseDragLayer; import java.util.ArrayList; @@ -201,7 +202,7 @@ public class PopupContainerWithArrow extends ArrowPopup implements DragSource, return null; } ItemInfo itemInfo = (ItemInfo) icon.getTag(); - if (!DeepShortcutManager.supportsShortcuts(itemInfo)) { + if (!ShortcutUtil.supportsShortcuts(itemInfo)) { return null; } diff --git a/src/com/android/launcher3/popup/PopupDataProvider.java b/src/com/android/launcher3/popup/PopupDataProvider.java index 6e4883e41..4612b2a47 100644 --- a/src/com/android/launcher3/popup/PopupDataProvider.java +++ b/src/com/android/launcher3/popup/PopupDataProvider.java @@ -29,14 +29,17 @@ import com.android.launcher3.notification.NotificationListener; import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.PackageUserKey; +import com.android.launcher3.util.ShortcutUtil; import com.android.launcher3.widget.WidgetListRowEntry; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -158,7 +161,7 @@ public class PopupDataProvider implements NotificationListener.NotificationsChan } public int getShortcutCountForItem(ItemInfo info) { - if (!DeepShortcutManager.supportsDeepShortcuts(info)) { + if (!ShortcutUtil.supportsDeepShortcuts(info)) { return 0; } ComponentName component = info.getTargetComponent(); @@ -171,7 +174,7 @@ public class PopupDataProvider implements NotificationListener.NotificationsChan } public @Nullable DotInfo getDotInfoForItem(@NonNull ItemInfo info) { - if (!DeepShortcutManager.supportsShortcuts(info)) { + if (!ShortcutUtil.supportsShortcuts(info)) { return null; } DotInfo dotInfo = mPackageUserToDotInfos.get(PackageUserKey.fromItemInfo(info)); @@ -243,13 +246,20 @@ public class PopupDataProvider implements NotificationListener.NotificationsChan */ public static @NonNull List getNotificationsForItem( @NonNull ItemInfo info, @NonNull List notifications) { - String shortcutId = DeepShortcutManager.getShortcutIdIfApplicable(info); + String shortcutId = ShortcutUtil.getShortcutIdIfPinnedShortcut(info); if (shortcutId == null) { return notifications; } - return notifications.stream().filter((NotificationKeyData notification) -> - shortcutId.equals(notification.shortcutId) - ).collect(Collectors.toList()); + String[] personKeys = ShortcutUtil.getPersonKeysIfPinnedShortcut(info); + return notifications.stream().filter((NotificationKeyData notification) -> { + if (notification.shortcutId != null) { + return notification.shortcutId.equals(shortcutId); + } + if (notification.personKeysFromNotification.length != 0) { + return Arrays.equals(notification.personKeysFromNotification, personKeys); + } + return false; + }).collect(Collectors.toList()); } public interface PopupDataChangeListener { diff --git a/src/com/android/launcher3/util/PackageUserKey.java b/src/com/android/launcher3/util/PackageUserKey.java index 1ce282210..e62451758 100644 --- a/src/com/android/launcher3/util/PackageUserKey.java +++ b/src/com/android/launcher3/util/PackageUserKey.java @@ -38,7 +38,7 @@ public class PackageUserKey { * @return Whether this PackageUserKey was successfully updated - it shouldn't be used if not. */ public boolean updateFromItemInfo(ItemInfo info) { - if (DeepShortcutManager.supportsShortcuts(info)) { + if (ShortcutUtil.supportsShortcuts(info)) { update(info.getTargetComponent().getPackageName(), info.user); return true; } diff --git a/src/com/android/launcher3/util/ShortcutUtil.java b/src/com/android/launcher3/util/ShortcutUtil.java new file mode 100644 index 000000000..792d69fc3 --- /dev/null +++ b/src/com/android/launcher3/util/ShortcutUtil.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2019 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.util; + +import com.android.launcher3.ItemInfo; +import com.android.launcher3.LauncherSettings; +import com.android.launcher3.Utilities; +import com.android.launcher3.WorkspaceItemInfo; +import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.shortcuts.ShortcutKey; + +public class ShortcutUtil { + public static boolean supportsShortcuts(ItemInfo info) { + return isActive(info) && (isApp(info) || isPinnedShortcut(info)); + } + + public static boolean supportsDeepShortcuts(ItemInfo info) { + return isActive(info) && isApp(info); + } + + public static String getShortcutIdIfPinnedShortcut(ItemInfo info) { + return isActive(info) && isPinnedShortcut(info) ? + ShortcutKey.fromItemInfo(info).getId() : null; + } + + public static String[] getPersonKeysIfPinnedShortcut(ItemInfo info) { + return isActive(info) && isPinnedShortcut(info) ? + ((WorkspaceItemInfo) info).getPersonKeys() : Utilities.EMPTY_STRING_ARRAY; + } + + private static boolean isActive(ItemInfo info) { + boolean isLoading = info instanceof WorkspaceItemInfo + && ((WorkspaceItemInfo) info).hasPromiseIconUi(); + return !isLoading && !info.isDisabled() && !FeatureFlags.GO_DISABLE_WIDGETS; + } + + private static boolean isApp(ItemInfo info) { + return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; + } + + private static boolean isPinnedShortcut(ItemInfo info) { + return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT + && info.container != ItemInfo.NO_ID + && info instanceof WorkspaceItemInfo; + } +} \ No newline at end of file diff --git a/src_shortcuts_overrides/com/android/launcher3/shortcuts/DeepShortcutManager.java b/src_shortcuts_overrides/com/android/launcher3/shortcuts/DeepShortcutManager.java index d89502b28..bd7dd86c4 100644 --- a/src_shortcuts_overrides/com/android/launcher3/shortcuts/DeepShortcutManager.java +++ b/src_shortcuts_overrides/com/android/launcher3/shortcuts/DeepShortcutManager.java @@ -27,10 +27,6 @@ import android.os.Bundle; import android.os.UserHandle; import android.util.Log; -import com.android.launcher3.ItemInfo; -import com.android.launcher3.LauncherSettings; -import com.android.launcher3.WorkspaceItemInfo; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -59,29 +55,6 @@ public class DeepShortcutManager { mLauncherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE); } - public static boolean supportsShortcuts(ItemInfo info) { - return isActive(info) && (isApp(info) || isPinnedShortcut(info)); - } - - public static boolean supportsDeepShortcuts(ItemInfo info) { - return isActive(info) && isApp(info); - } - - public static String getShortcutIdIfApplicable(ItemInfo info) { - return isActive(info) && isPinnedShortcut(info) ? - ShortcutKey.fromItemInfo(info).getId() : null; - } - - private static boolean isApp(ItemInfo info) { - return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; - } - - private static boolean isPinnedShortcut(ItemInfo info) { - return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT - && info.container != ItemInfo.NO_ID - && info instanceof WorkspaceItemInfo; - } - /** * Queries for the shortcuts with the package name and provided ids. * @@ -182,12 +155,6 @@ public class DeepShortcutManager { return shortcutIds; } - private static boolean isActive(ItemInfo info) { - boolean isLoading = info instanceof WorkspaceItemInfo - && ((WorkspaceItemInfo) info).hasPromiseIconUi(); - return !isLoading && !info.isDisabled(); - } - /** * Query the system server for all the shortcuts matching the given parameters. * If packageName == null, we query for all shortcuts with the passed flags, regardless of app. diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java index 5cc64dc9a..467ae02d5 100644 --- a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java +++ b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java @@ -17,9 +17,11 @@ package com.android.launcher3.uioverrides; import android.app.Activity; +import android.app.Person; import android.content.Context; import android.content.Intent; import android.content.IntentSender; +import android.content.pm.ShortcutInfo; import android.os.Bundle; import android.os.CancellationSignal; @@ -27,6 +29,7 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState.ScaleAndTranslation; import com.android.launcher3.LauncherStateManager.StateHandler; +import com.android.launcher3.Utilities; import com.android.launcher3.graphics.RotationMode; import com.android.launcher3.util.TouchController; @@ -95,4 +98,7 @@ public class UiFactory { public static void clearSwipeSharedState(boolean finishAnimation) {} + public static Person[] getPersons(ShortcutInfo si) { + return Utilities.EMPTY_PERSON_ARRAY; + } } -- cgit v1.2.3