show dot in deep shortcuts when notification contains exactly identical
set of person Bug: 132336512 Change-Id: I975524e28168c10a186cdc24b188c161faf433cf
This commit is contained in:
parent
1a4b815cd8
commit
49a3e699f9
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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<String> extractKeysOnly(@NonNull List<NotificationKeyData> notificationKeys) {
|
||||
public static List<String> extractKeysOnly(
|
||||
@NonNull List<NotificationKeyData> notificationKeys) {
|
||||
List<String> 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<Person> 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)) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<NotificationKeyData> getNotificationsForItem(
|
||||
@NonNull ItemInfo info, @NonNull List<NotificationKeyData> 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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue