diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarShortcutMenuAccessibilityDelegate.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarShortcutMenuAccessibilityDelegate.java index bfbecf3f77..25db960ea3 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarShortcutMenuAccessibilityDelegate.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarShortcutMenuAccessibilityDelegate.java @@ -16,7 +16,6 @@ package com.android.launcher3.taskbar; import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.DEEP_SHORTCUTS; -import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.SHORTCUTS_AND_NOTIFICATIONS; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT; import static com.android.launcher3.util.SplitConfigurationOptions.getLogEventForPosition; @@ -36,7 +35,6 @@ import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.model.data.WorkspaceItemInfo; -import com.android.launcher3.notification.NotificationListener; import com.android.launcher3.util.ShortcutUtil; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.util.LogUtils; @@ -63,8 +61,6 @@ public class TaskbarShortcutMenuAccessibilityDelegate mActions.put(DEEP_SHORTCUTS, new LauncherAction(DEEP_SHORTCUTS, R.string.action_deep_shortcut, KeyEvent.KEYCODE_S)); - mActions.put(SHORTCUTS_AND_NOTIFICATIONS, new LauncherAction(DEEP_SHORTCUTS, - R.string.shortcuts_menu_with_notifications_description, KeyEvent.KEYCODE_S)); mActions.put(MOVE_TO_TOP_OR_LEFT, new LauncherAction( MOVE_TO_TOP_OR_LEFT, R.string.move_drop_target_top_or_left, KeyEvent.KEYCODE_L)); mActions.put(MOVE_TO_BOTTOM_OR_RIGHT, new LauncherAction( @@ -76,8 +72,7 @@ public class TaskbarShortcutMenuAccessibilityDelegate @Override protected void getSupportedActions(View host, ItemInfo item, List out) { if (ShortcutUtil.supportsShortcuts(item)) { - out.add(mActions.get(NotificationListener.getInstanceIfConnected() != null - ? SHORTCUTS_AND_NOTIFICATIONS : DEEP_SHORTCUTS)); + out.add(mActions.get(DEEP_SHORTCUTS)); } out.add(mActions.get(MOVE_TO_TOP_OR_LEFT)); out.add(mActions.get(MOVE_TO_BOTTOM_OR_RIGHT)); @@ -117,7 +112,7 @@ public class TaskbarShortcutMenuAccessibilityDelegate instanceIds.first); } return true; - } else if (action == DEEP_SHORTCUTS || action == SHORTCUTS_AND_NOTIFICATIONS) { + } else if (action == DEEP_SHORTCUTS) { mContext.showPopupMenuForIcon((BubbleTextView) host); return true; diff --git a/res/drawable/notification_circle.xml b/res/drawable/notification_circle.xml deleted file mode 100644 index 65fbaea5a6..0000000000 --- a/res/drawable/notification_circle.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/res/layout/notification_content.xml b/res/layout/notification_content.xml deleted file mode 100644 index 0763d48b79..0000000000 --- a/res/layout/notification_content.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/res/values/config.xml b/res/values/config.xml index 47756bae56..2a8ec2854a 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -119,8 +119,6 @@ - - diff --git a/res/values/strings.xml b/res/values/strings.xml index fb55c75a5d..5efe940555 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -402,9 +402,6 @@ Shortcuts - - Shortcuts and notifications - Dismiss @@ -412,9 +409,6 @@ Close - - Notification dismissed - Personal diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java index 758bffbeb8..ac5b528e68 100644 --- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java +++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java @@ -37,7 +37,6 @@ import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.LauncherAppWidgetInfo; import com.android.launcher3.model.data.WorkspaceItemFactory; import com.android.launcher3.model.data.WorkspaceItemInfo; -import com.android.launcher3.notification.NotificationListener; import com.android.launcher3.popup.ArrowPopup; import com.android.launcher3.popup.PopupContainerWithArrow; import com.android.launcher3.touch.ItemLongClickListener; @@ -70,7 +69,6 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate out) { if ((host.getParent() instanceof DeepShortcutView)) { out.add(mActions.get(ADD_TO_WORKSPACE)); - } else if (host instanceof NotificationMainView) { - if (((NotificationMainView) host).canChildBeDismissed()) { - out.add(mActions.get(DISMISS_NOTIFICATION)); - } } } @@ -80,13 +70,6 @@ public class ShortcutMenuAccessibilityDelegate extends LauncherAccessibilityDele announceConfirmation(R.string.item_added_to_workspace); })); return true; - } else if (action == DISMISS_NOTIFICATION) { - if (!(host instanceof NotificationMainView)) { - return false; - } - ((NotificationMainView) host).onChildDismissed(); - announceConfirmation(R.string.notification_dismissed); - return true; } return false; } diff --git a/src/com/android/launcher3/dot/DotInfo.java b/src/com/android/launcher3/dot/DotInfo.java index fc180d1c17..64864b01cd 100644 --- a/src/com/android/launcher3/dot/DotInfo.java +++ b/src/com/android/launcher3/dot/DotInfo.java @@ -18,7 +18,6 @@ package com.android.launcher3.dot; import androidx.annotation.NonNull; -import com.android.launcher3.notification.NotificationInfo; import com.android.launcher3.notification.NotificationKeyData; import java.util.ArrayList; @@ -32,8 +31,7 @@ public class DotInfo { public static final int MAX_COUNT = 999; /** - * The keys of the notifications that this dot represents. These keys can later be - * used to retrieve {@link NotificationInfo}'s. + * The keys of the notifications that this dot represents. */ private final List mNotificationKeys = new ArrayList<>(); diff --git a/src/com/android/launcher3/notification/NotificationContainer.java b/src/com/android/launcher3/notification/NotificationContainer.java deleted file mode 100644 index 7cc9ad38bc..0000000000 --- a/src/com/android/launcher3/notification/NotificationContainer.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * 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.notification; - -import static com.android.app.animation.Interpolators.scrollInterpolatorForVelocity; -import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL; - -import android.animation.Animator; -import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; -import android.content.Context; -import android.graphics.Rect; -import android.util.AttributeSet; -import android.util.FloatProperty; -import android.view.MotionEvent; -import android.view.View; -import android.widget.FrameLayout; - -import com.android.launcher3.R; -import com.android.launcher3.anim.AnimationSuccessListener; -import com.android.launcher3.popup.PopupContainerWithArrow; -import com.android.launcher3.touch.BaseSwipeDetector; -import com.android.launcher3.touch.OverScroll; -import com.android.launcher3.touch.SingleAxisSwipeDetector; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * Class to manage the notification UI in a {@link PopupContainerWithArrow}. - * - * - Has two {@link NotificationMainView} that represent the top two notifications - * - Handles dismissing a notification - */ -public class NotificationContainer extends FrameLayout implements SingleAxisSwipeDetector.Listener { - - private static final FloatProperty DRAG_TRANSLATION_X = - new FloatProperty("notificationProgress") { - @Override - public void setValue(NotificationContainer view, float transX) { - view.setDragTranslationX(transX); - } - - @Override - public Float get(NotificationContainer view) { - return view.mDragTranslationX; - } - }; - - private static final Rect sTempRect = new Rect(); - - private final SingleAxisSwipeDetector mSwipeDetector; - private final List mNotificationInfos = new ArrayList<>(); - private boolean mIgnoreTouch = false; - - private final ObjectAnimator mContentTranslateAnimator; - private float mDragTranslationX = 0; - - private final NotificationMainView mPrimaryView; - private final NotificationMainView mSecondaryView; - private PopupContainerWithArrow mPopupContainer; - - public NotificationContainer(Context context) { - this(context, null, 0); - } - - public NotificationContainer(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public NotificationContainer(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - mSwipeDetector = new SingleAxisSwipeDetector(getContext(), this, HORIZONTAL); - mSwipeDetector.setDetectableScrollConditions(SingleAxisSwipeDetector.DIRECTION_BOTH, false); - mContentTranslateAnimator = ObjectAnimator.ofFloat(this, DRAG_TRANSLATION_X, 0); - - mPrimaryView = (NotificationMainView) View.inflate(getContext(), - R.layout.notification_content, null); - mSecondaryView = (NotificationMainView) View.inflate(getContext(), - R.layout.notification_content, null); - mSecondaryView.setAlpha(0); - - addView(mSecondaryView); - addView(mPrimaryView); - - } - - public void setPopupView(PopupContainerWithArrow popupView) { - mPopupContainer = popupView; - } - - /** - * Returns true if we should intercept the swipe. - */ - public boolean onInterceptSwipeEvent(MotionEvent ev) { - if (ev.getAction() == MotionEvent.ACTION_DOWN) { - sTempRect.set(getLeft(), getTop(), getRight(), getBottom()); - mIgnoreTouch = !sTempRect.contains((int) ev.getX(), (int) ev.getY()); - if (!mIgnoreTouch) { - mPopupContainer.getParent().requestDisallowInterceptTouchEvent(true); - } - } - if (mIgnoreTouch) { - return false; - } - if (mPrimaryView.getNotificationInfo() == null) { - // The notification hasn't been populated yet. - return false; - } - - mSwipeDetector.onTouchEvent(ev); - return mSwipeDetector.isDraggingOrSettling(); - } - - /** - * Returns true when we should handle the swipe. - */ - public boolean onSwipeEvent(MotionEvent ev) { - if (mIgnoreTouch) { - return false; - } - if (mPrimaryView.getNotificationInfo() == null) { - // The notification hasn't been populated yet. - return false; - } - return mSwipeDetector.onTouchEvent(ev); - } - - /** - * Applies the list of @param notificationInfos to this container. - */ - public void applyNotificationInfos(final List notificationInfos) { - mNotificationInfos.clear(); - if (notificationInfos.isEmpty()) { - mPrimaryView.applyNotificationInfo(null); - mSecondaryView.applyNotificationInfo(null); - return; - } - mNotificationInfos.addAll(notificationInfos); - - NotificationInfo mainNotification = notificationInfos.get(0); - mPrimaryView.applyNotificationInfo(mainNotification); - mSecondaryView.applyNotificationInfo(notificationInfos.size() > 1 - ? notificationInfos.get(1) - : null); - } - - /** - * Trims the notifications. - * @param notificationKeys List of all valid notification keys. - */ - public void trimNotifications(final List notificationKeys) { - Iterator iterator = mNotificationInfos.iterator(); - while (iterator.hasNext()) { - if (!notificationKeys.contains(iterator.next().notificationKey)) { - iterator.remove(); - } - } - - NotificationInfo primaryInfo = mNotificationInfos.size() > 0 - ? mNotificationInfos.get(0) - : null; - NotificationInfo secondaryInfo = mNotificationInfos.size() > 1 - ? mNotificationInfos.get(1) - : null; - - mPrimaryView.applyNotificationInfo(primaryInfo); - mSecondaryView.applyNotificationInfo(secondaryInfo); - - mPrimaryView.onPrimaryDrag(0); - mSecondaryView.onSecondaryDrag(0); - } - - private void setDragTranslationX(float translationX) { - mDragTranslationX = translationX; - - float progress = translationX / getWidth(); - mPrimaryView.onPrimaryDrag(progress); - if (mSecondaryView.getNotificationInfo() == null) { - mSecondaryView.setAlpha(0f); - } else { - mSecondaryView.onSecondaryDrag(progress); - } - } - - // SingleAxisSwipeDetector.Listener's - @Override - public void onDragStart(boolean start, float startDisplacement) { - mPopupContainer.showArrow(false); - } - - @Override - public boolean onDrag(float displacement) { - if (!mPrimaryView.canChildBeDismissed()) { - displacement = OverScroll.dampedScroll(displacement, getWidth()); - } - - float progress = displacement / getWidth(); - mPrimaryView.onPrimaryDrag(progress); - if (mSecondaryView.getNotificationInfo() == null) { - mSecondaryView.setAlpha(0f); - } else { - mSecondaryView.onSecondaryDrag(progress); - } - mContentTranslateAnimator.cancel(); - return true; - } - - @Override - public void onDragEnd(float velocity) { - final boolean willExit; - final float endTranslation; - final float startTranslation = mPrimaryView.getTranslationX(); - final float width = getWidth(); - - if (!mPrimaryView.canChildBeDismissed()) { - willExit = false; - endTranslation = 0; - } else if (mSwipeDetector.isFling(velocity)) { - willExit = true; - endTranslation = velocity < 0 ? -width : width; - } else if (Math.abs(startTranslation) > width / 2f) { - willExit = true; - endTranslation = (startTranslation < 0 ? -width : width); - } else { - willExit = false; - endTranslation = 0; - } - - long duration = BaseSwipeDetector.calculateDuration(velocity, - (endTranslation - startTranslation) / width); - - mContentTranslateAnimator.removeAllListeners(); - mContentTranslateAnimator.setDuration(duration) - .setInterpolator(scrollInterpolatorForVelocity(velocity)); - mContentTranslateAnimator.setFloatValues(startTranslation, endTranslation); - - NotificationMainView current = mPrimaryView; - mContentTranslateAnimator.addListener(new AnimationSuccessListener() { - @Override - public void onAnimationSuccess(Animator animator) { - mSwipeDetector.finishedScrolling(); - if (willExit) { - current.onChildDismissed(); - } - mPopupContainer.showArrow(true); - } - }); - mContentTranslateAnimator.start(); - } - - /** - * Animates the background color to a new color. - * @param color The color to change to. - * @param animatorSetOut The AnimatorSet where we add the color animator to. - */ - public void updateBackgroundColor(int color, AnimatorSet animatorSetOut) { - mPrimaryView.updateBackgroundColor(color, animatorSetOut); - mSecondaryView.updateBackgroundColor(color, animatorSetOut); - } - - /** - * Updates the header with a new @param notificationCount. - */ - public void updateHeader(int notificationCount) { - mPrimaryView.updateHeader(notificationCount); - mSecondaryView.updateHeader(notificationCount - 1); - } -} diff --git a/src/com/android/launcher3/notification/NotificationInfo.java b/src/com/android/launcher3/notification/NotificationInfo.java deleted file mode 100644 index f4468fdf01..0000000000 --- a/src/com/android/launcher3/notification/NotificationInfo.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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.notification; - -import static com.android.launcher3.AbstractFloatingView.TYPE_ACTION_POPUP; -import static com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_ALL_APPS; -import static com.android.launcher3.Utilities.allowBGLaunch; -import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_LAUNCH_TAP; - -import android.app.ActivityOptions; -import android.app.Notification; -import android.app.PendingIntent; -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.Icon; -import android.service.notification.StatusBarNotification; -import android.view.View; - -import com.android.launcher3.AbstractFloatingView; -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 - * only be created when we need to show the notification contents on the UI; until then, a - * {@link DotInfo} with only the notification key should - * be passed around, and then this can be constructed using the StatusBarNotification from - * {@link NotificationListener#getNotificationsForKeys(java.util.List)}. - */ -public class NotificationInfo implements View.OnClickListener { - - public final PackageUserKey packageUserKey; - public final String notificationKey; - public final CharSequence title; - public final CharSequence text; - public final PendingIntent intent; - public final boolean autoCancel; - public final boolean dismissable; - - private final ItemInfo mItemInfo; - private Drawable mIconDrawable; - private int mIconColor; - private boolean mIsIconLarge; - - /** - * Extracts the data that we need from the StatusBarNotification. - */ - public NotificationInfo(Context context, StatusBarNotification statusBarNotification, - ItemInfo itemInfo) { - packageUserKey = PackageUserKey.fromNotification(statusBarNotification); - notificationKey = statusBarNotification.getKey(); - Notification notification = statusBarNotification.getNotification(); - title = notification.extras.getCharSequence(Notification.EXTRA_TITLE); - text = notification.extras.getCharSequence(Notification.EXTRA_TEXT); - - int iconType = notification.getBadgeIconType(); - // Load the icon. Since it is backed by ashmem, we won't copy the entire bitmap - // into our process as long as we don't touch it and it exists in systemui. - Icon icon = iconType == Notification.BADGE_ICON_SMALL ? null : notification.getLargeIcon(); - if (icon == null) { - // Use the small icon. - icon = notification.getSmallIcon(); - mIconDrawable = icon == null ? null : icon.loadDrawable(context); - mIconColor = statusBarNotification.getNotification().color; - mIsIconLarge = false; - } else { - // Use the large icon. - mIconDrawable = icon.loadDrawable(context); - mIsIconLarge = true; - } - if (mIconDrawable == null) { - mIconDrawable = LauncherAppState.getInstance(context).getIconCache() - .getDefaultIcon(statusBarNotification.getUser()).newIcon(context); - } - intent = notification.contentIntent; - autoCancel = (notification.flags & Notification.FLAG_AUTO_CANCEL) != 0; - dismissable = (notification.flags & Notification.FLAG_ONGOING_EVENT) == 0; - this.mItemInfo = itemInfo; - } - - @Override - public void onClick(View view) { - if (intent == null) { - return; - } - final ActivityContext context = ActivityContext.lookupContext(view.getContext()); - ActivityOptions options = allowBGLaunch(ActivityOptions.makeClipRevealAnimation( - view, 0, 0, view.getWidth(), view.getHeight())); - try { - intent.send(null, 0, null, null, null, null, options.toBundle()); - context.getStatsLogManager().logger().withItemInfo(mItemInfo) - .log(LAUNCHER_NOTIFICATION_LAUNCH_TAP); - } catch (PendingIntent.CanceledException e) { - e.printStackTrace(); - } - if (autoCancel) { - PopupDataProvider popupDataProvider = context.getPopupDataProvider(); - if (popupDataProvider != null) { - popupDataProvider.cancelNotification(notificationKey); - } - } - AbstractFloatingView.closeOpenViews( - context, true, TYPE_ACTION_POPUP | TYPE_TASKBAR_ALL_APPS); - } - - public Drawable getIconForBackground(Context context, int background) { - if (mIsIconLarge) { - // Only small icons should be tinted. - return mIconDrawable; - } - mIconColor = IconPalette.resolveContrastColor(context, mIconColor, background); - Drawable icon = mIconDrawable.mutate(); - // DrawableContainer ignores the color filter if it's already set, so clear it first to - // get it set and invalidated properly. - icon.setTintList(null); - icon.setTint(mIconColor); - return icon; - } -} diff --git a/src/com/android/launcher3/notification/NotificationKeyData.java b/src/com/android/launcher3/notification/NotificationKeyData.java index 1dda3dfd27..4115b3da5c 100644 --- a/src/com/android/launcher3/notification/NotificationKeyData.java +++ b/src/com/android/launcher3/notification/NotificationKeyData.java @@ -26,13 +26,10 @@ import androidx.annotation.Nullable; import com.android.launcher3.Utilities; import java.util.ArrayList; -import java.util.List; /** * The key data associated with the notification, used to determine what to include * in dots and stub popup views before they are populated. - * - * @see NotificationInfo for the full data used when populating the stub views. */ public class NotificationKeyData { public final String notificationKey; @@ -56,15 +53,6 @@ public class NotificationKeyData { Notification.EXTRA_PEOPLE_LIST))); } - public static List extractKeysOnly( - @NonNull List notificationKeys) { - List keysOnly = new ArrayList<>(notificationKeys.size()); - for (NotificationKeyData notificationKeyData : notificationKeys) { - keysOnly.add(notificationKeyData.notificationKey); - } - return keysOnly; - } - private static String[] extractPersonKeyOnly(@Nullable ArrayList people) { if (people == null || people.isEmpty()) { return Utilities.EMPTY_STRING_ARRAY; diff --git a/src/com/android/launcher3/notification/NotificationListener.java b/src/com/android/launcher3/notification/NotificationListener.java index 04eb38a3c5..836ea4aefe 100644 --- a/src/com/android/launcher3/notification/NotificationListener.java +++ b/src/com/android/launcher3/notification/NotificationListener.java @@ -34,7 +34,6 @@ import android.util.ArraySet; import android.util.Log; import android.util.Pair; -import androidx.annotation.AnyThread; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; @@ -64,8 +63,7 @@ public class NotificationListener extends NotificationListenerService { private static final int MSG_NOTIFICATION_POSTED = 1; private static final int MSG_NOTIFICATION_REMOVED = 2; private static final int MSG_NOTIFICATION_FULL_REFRESH = 3; - private static final int MSG_CANCEL_NOTIFICATION = 4; - private static final int MSG_RANKING_UPDATE = 5; + private static final int MSG_RANKING_UPDATE = 4; private static NotificationListener sNotificationListenerInstance = null; private static final ArraySet sNotificationsChangedListeners = @@ -81,9 +79,6 @@ public class NotificationListener extends NotificationListenerService { /** Maps keys to their corresponding current group key */ private final Map mNotificationGroupKeyMap = new HashMap<>(); - /** The last notification key that was dismissed from launcher UI */ - private String mLastKeyDismissedByLauncher; - private SettingsCache mSettingsCache; private SettingsCache.OnChangeListener mNotificationSettingsChangedListener; @@ -93,7 +88,7 @@ public class NotificationListener extends NotificationListenerService { sNotificationListenerInstance = this; } - public static @Nullable NotificationListener getInstanceIfConnected() { + private static @Nullable NotificationListener getInstanceIfConnected() { return sIsConnected ? sNotificationListenerInstance : null; } @@ -139,17 +134,9 @@ public class NotificationListener extends NotificationListenerService { if (notificationGroup != null) { notificationGroup.removeChildKey(key); if (notificationGroup.isEmpty()) { - if (key.equals(mLastKeyDismissedByLauncher)) { - // Only cancel the group notification if launcher dismissed the - // last child. - cancelNotification(notificationGroup.getGroupSummaryKey()); - } mNotificationGroupMap.remove(sbn.getGroupKey()); } } - if (key.equals(mLastKeyDismissedByLauncher)) { - mLastKeyDismissedByLauncher = null; - } return true; } case MSG_NOTIFICATION_FULL_REFRESH: @@ -164,11 +151,6 @@ public class NotificationListener extends NotificationListenerService { mUiHandler.obtainMessage(message.what, activeNotifications).sendToTarget(); return true; - case MSG_CANCEL_NOTIFICATION: { - mLastKeyDismissedByLauncher = (String) message.obj; - cancelNotification(mLastKeyDismissedByLauncher); - return true; - } case MSG_RANKING_UPDATE: { String[] keys = ((RankingMap) message.obj).getOrderedKeys(); for (StatusBarNotification sbn : getActiveNotificationsSafely(keys)) { @@ -272,14 +254,6 @@ public class NotificationListener extends NotificationListenerService { mWorkerHandler.obtainMessage(MSG_RANKING_UPDATE, rankingMap).sendToTarget(); } - /** - * Cancels a notification - */ - @AnyThread - public void cancelNotificationFromLauncher(String key) { - mWorkerHandler.obtainMessage(MSG_CANCEL_NOTIFICATION, key).sendToTarget(); - } - @WorkerThread private void updateGroupKeyIfNecessary(StatusBarNotification sbn) { String childKey = sbn.getKey(); @@ -314,15 +288,6 @@ public class NotificationListener extends NotificationListenerService { } } - /** - * This makes a potentially expensive binder call and should be run on a background thread. - */ - @WorkerThread - public List getNotificationsForKeys(List keys) { - return Arrays.asList(getActiveNotificationsSafely( - keys.stream().map(n -> n.notificationKey).toArray(String[]::new))); - } - /** * Returns true for notifications that have an intent and are not headers for grouped * notifications and should be shown in the notification popup. diff --git a/src/com/android/launcher3/notification/NotificationMainView.java b/src/com/android/launcher3/notification/NotificationMainView.java deleted file mode 100644 index ecd018b26d..0000000000 --- a/src/com/android/launcher3/notification/NotificationMainView.java +++ /dev/null @@ -1,332 +0,0 @@ -/* - * 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.notification; - -import static com.android.app.animation.Interpolators.LINEAR; -import static com.android.launcher3.Utilities.mapToRange; -import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DISMISSED; - -import android.animation.AnimatorSet; -import android.animation.ValueAnimator; -import android.annotation.TargetApi; -import android.content.Context; -import android.graphics.Outline; -import android.graphics.Rect; -import android.graphics.drawable.GradientDrawable; -import android.os.Build; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewOutlineProvider; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.annotation.Nullable; - -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, - * e.g. icon + title + text. - */ -@TargetApi(Build.VERSION_CODES.N) -public class NotificationMainView extends LinearLayout { - - // This is used only to track the notification view, so that it can be properly logged. - public static final ItemInfo NOTIFICATION_ITEM_INFO = new ItemInfo(); - - // Value when the primary notification main view will be gone (zero alpha). - private static final float PRIMARY_GONE_PROGRESS = 0.7f; - private static final float PRIMARY_MIN_PROGRESS = 0.40f; - private static final float PRIMARY_MAX_PROGRESS = 0.60f; - private static final float SECONDARY_MIN_PROGRESS = 0.30f; - private static final float SECONDARY_MAX_PROGRESS = 0.50f; - private static final float SECONDARY_CONTENT_MAX_PROGRESS = 0.6f; - - private NotificationInfo mNotificationInfo; - private int mBackgroundColor; - private TextView mTitleView; - private TextView mTextView; - private View mIconView; - - private View mHeader; - private View mMainView; - - private TextView mHeaderCount; - private final Rect mOutline = new Rect(); - - // Space between notifications during swipe - private final int mNotificationSpace; - private final int mMaxTransX; - private final int mMaxElevation; - - private final GradientDrawable mBackground; - - public NotificationMainView(Context context) { - this(context, null, 0); - } - - public NotificationMainView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public NotificationMainView(Context context, AttributeSet attrs, int defStyle) { - this(context, attrs, defStyle, 0); - } - - public NotificationMainView(Context context, AttributeSet attrs, int defStyle, int defStylRes) { - super(context, attrs, defStyle, defStylRes); - - float outlineRadius = Themes.getDialogCornerRadius(context); - - mBackground = new GradientDrawable(); - mBackground.setColor(Themes.getAttrColor(context, R.attr.popupColorPrimary)); - mBackground.setCornerRadius(outlineRadius); - setBackground(mBackground); - - mMaxElevation = getResources().getDimensionPixelSize(R.dimen.deep_shortcuts_elevation); - setElevation(mMaxElevation); - - mMaxTransX = getResources().getDimensionPixelSize(R.dimen.notification_max_trans); - mNotificationSpace = getResources().getDimensionPixelSize(R.dimen.notification_space); - - setClipToOutline(true); - setOutlineProvider(new ViewOutlineProvider() { - @Override - public void getOutline(View view, Outline outline) { - outline.setRoundRect(mOutline, outlineRadius); - } - }); - } - - /** - * Updates the header text. - * @param notificationCount The number of notifications. - */ - public void updateHeader(int notificationCount) { - final String text; - final int visibility; - if (notificationCount <= 1) { - text = ""; - visibility = View.INVISIBLE; - } else { - text = String.valueOf(notificationCount); - visibility = View.VISIBLE; - - } - mHeaderCount.setText(text); - mHeaderCount.setVisibility(visibility); - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - - ViewGroup textAndBackground = findViewById(R.id.text_and_background); - mTitleView = textAndBackground.findViewById(R.id.title); - mTextView = textAndBackground.findViewById(R.id.text); - mIconView = findViewById(R.id.popup_item_icon); - mHeaderCount = findViewById(R.id.notification_count); - - mHeader = findViewById(R.id.header); - mMainView = findViewById(R.id.main_view); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - mOutline.set(0, 0, getWidth(), getHeight()); - invalidateOutline(); - } - - private void updateBackgroundColor(int color) { - mBackgroundColor = color; - mBackground.setColor(color); - if (mNotificationInfo != null) { - mIconView.setBackground(mNotificationInfo.getIconForBackground(getContext(), - mBackgroundColor)); - } - } - - /** - * Animates the background color to a new color. - * @param color The color to change to. - * @param animatorSetOut The AnimatorSet where we add the color animator to. - */ - public void updateBackgroundColor(int color, AnimatorSet animatorSetOut) { - int oldColor = mBackgroundColor; - ValueAnimator colors = ValueAnimator.ofArgb(oldColor, color); - colors.addUpdateListener(valueAnimator -> { - int newColor = (int) valueAnimator.getAnimatedValue(); - updateBackgroundColor(newColor); - }); - animatorSetOut.play(colors); - } - - /** - * Sets the content of this view, animating it after a new icon shifts up if necessary. - */ - public void applyNotificationInfo(NotificationInfo notificationInfo) { - mNotificationInfo = notificationInfo; - if (notificationInfo == null) { - return; - } - NotificationListener listener = NotificationListener.getInstanceIfConnected(); - if (listener != null) { - listener.setNotificationsShown(new String[] {mNotificationInfo.notificationKey}); - } - CharSequence title = mNotificationInfo.title; - CharSequence text = mNotificationInfo.text; - if (!TextUtils.isEmpty(title) && !TextUtils.isEmpty(text)) { - mTitleView.setText(title.toString()); - mTextView.setText(text.toString()); - } else { - mTitleView.setMaxLines(2); - mTitleView.setText(TextUtils.isEmpty(title) ? text.toString() : title.toString()); - mTextView.setVisibility(GONE); - } - mIconView.setBackground(mNotificationInfo.getIconForBackground(getContext(), - mBackgroundColor)); - if (mNotificationInfo.intent != null) { - setOnClickListener(mNotificationInfo); - } - - // Add a stub ItemInfo so that logging populates the correct container and item types - // instead of DEFAULT_CONTAINERTYPE and DEFAULT_ITEMTYPE, respectively. - setTag(NOTIFICATION_ITEM_INFO); - } - - /** - * Sets the alpha of only the child views. - */ - public void setContentAlpha(float alpha) { - mHeader.setAlpha(alpha); - mMainView.setAlpha(alpha); - } - - /** - * Sets the translation of only the child views. - */ - public void setContentTranslationX(float transX) { - mHeader.setTranslationX(transX); - mMainView.setTranslationX(transX); - } - - /** - * Updates the alpha, content alpha, and elevation of this view. - * - * @param progress Range from [0, 1] or [-1, 0] - * When 0: Full alpha - * When 1/-1: zero alpha - */ - public void onPrimaryDrag(float progress) { - float absProgress = Math.abs(progress); - final int width = getWidth(); - - float min = PRIMARY_MIN_PROGRESS; - float max = PRIMARY_MAX_PROGRESS; - - if (absProgress < min) { - setAlpha(1f); - setContentAlpha(1); - setElevation(mMaxElevation); - } else if (absProgress < max) { - setAlpha(1f); - setContentAlpha(mapToRange(absProgress, min, max, 1f, 0f, LINEAR)); - setElevation(Utilities.mapToRange(absProgress, min, max, mMaxElevation, 0, LINEAR)); - } else { - setAlpha(mapToRange(absProgress, max, PRIMARY_GONE_PROGRESS, 1f, 0f, LINEAR)); - setContentAlpha(0f); - setElevation(0f); - } - - setTranslationX(width * progress); - } - - /** - * Updates the alpha, content alpha, elevation, and clipping of this view. - * @param progress Range from [0, 1] or [-1, 0] - * When 0: Smallest clipping, zero alpha - * When 1/-1: Full clip, full alpha - */ - public void onSecondaryDrag(float progress) { - final float absProgress = Math.abs(progress); - - float min = SECONDARY_MIN_PROGRESS; - float max = SECONDARY_MAX_PROGRESS; - float contentMax = SECONDARY_CONTENT_MAX_PROGRESS; - - if (absProgress < min) { - setAlpha(0f); - setContentAlpha(0); - setElevation(0f); - } else if (absProgress < max) { - setAlpha(mapToRange(absProgress, min, max, 0, 1f, LINEAR)); - setContentAlpha(0f); - setElevation(0f); - } else { - setAlpha(1f); - setContentAlpha(absProgress > contentMax - ? 1f - : mapToRange(absProgress, max, contentMax, 0, 1f, LINEAR)); - setElevation(Utilities.mapToRange(absProgress, max, 1, 0, mMaxElevation, LINEAR)); - } - - final int width = getWidth(); - int crop = (int) (width * absProgress); - int space = (int) (absProgress > PRIMARY_GONE_PROGRESS - ? mapToRange(absProgress, PRIMARY_GONE_PROGRESS, 1f, mNotificationSpace, 0, LINEAR) - : mNotificationSpace); - if (progress < 0) { - mOutline.left = Math.max(0, getWidth() - crop + space); - mOutline.right = getWidth(); - } else { - mOutline.right = Math.min(getWidth(), crop - space); - mOutline.left = 0; - } - - float contentTransX = mMaxTransX * (1f - absProgress); - setContentTranslationX(progress < 0 - ? contentTransX - : -contentTransX); - invalidateOutline(); - } - - public @Nullable NotificationInfo getNotificationInfo() { - return mNotificationInfo; - } - - public boolean canChildBeDismissed() { - return mNotificationInfo != null && mNotificationInfo.dismissable; - } - - public void onChildDismissed() { - 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/PopupDataProvider.java b/src/com/android/launcher3/popup/PopupDataProvider.java index 44e3dd6390..962dffd636 100644 --- a/src/com/android/launcher3/popup/PopupDataProvider.java +++ b/src/com/android/launcher3/popup/PopupDataProvider.java @@ -36,7 +36,6 @@ import com.android.launcher3.widget.model.WidgetsListContentEntry; import java.io.PrintWriter; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -73,7 +72,6 @@ public class PopupDataProvider implements NotificationListener.NotificationsChan private void updateNotificationDots(Predicate updatedDots) { mNotificationDotsChangeListener.accept(updatedDots); - mChangeListener.onNotificationDotsUpdated(updatedDots); } @Override @@ -98,7 +96,6 @@ public class PopupDataProvider implements NotificationListener.NotificationsChan mPackageUserToDotInfos.remove(removedPackageUserKey); } updateNotificationDots(removedPackageUserKey::equals); - trimNotifications(mPackageUserToDotInfos); } } @@ -136,11 +133,6 @@ public class PopupDataProvider implements NotificationListener.NotificationsChan if (!updatedDots.isEmpty()) { updateNotificationDots(updatedDots::containsKey); } - trimNotifications(updatedDots); - } - - private void trimNotifications(Map updatedDots) { - mChangeListener.trimNotifications(updatedDots); } public void setDeepShortcutMap(HashMap deepShortcutMapCopy) { @@ -169,26 +161,23 @@ public class PopupDataProvider implements NotificationListener.NotificationsChan if (dotInfo == null) { return null; } - List notifications = getNotificationsForItem( - info, dotInfo.getNotificationKeys()); - if (notifications.isEmpty()) { - return null; - } - return dotInfo; - } - public @NonNull List getNotificationKeysForItem(ItemInfo info) { - DotInfo dotInfo = getDotInfoForItem(info); - return dotInfo == null ? Collections.EMPTY_LIST - : getNotificationsForItem(info, dotInfo.getNotificationKeys()); - } - - public void cancelNotification(String notificationKey) { - NotificationListener notificationListener = NotificationListener.getInstanceIfConnected(); - if (notificationListener == null) { - return; + // If the item represents a pinned shortcut, ensure that there is a notification + // for this shortcut + String shortcutId = ShortcutUtil.getShortcutIdIfPinnedShortcut(info); + if (shortcutId == null) { + return dotInfo; } - notificationListener.cancelNotificationFromLauncher(notificationKey); + String[] personKeys = ShortcutUtil.getPersonKeysIfPinnedShortcut(info); + return (dotInfo.getNotificationKeys().stream().anyMatch(notification -> { + if (notification.shortcutId != null) { + return notification.shortcutId.equals(shortcutId); + } + if (notification.personKeysFromNotification.length != 0) { + return Arrays.equals(notification.personKeysFromNotification, personKeys); + } + return false; + })) ? dotInfo : null; } /** @@ -247,27 +236,6 @@ public class PopupDataProvider implements NotificationListener.NotificationsChan .orElse(null); } - /** - * Returns a list of notifications that are relevant to given ItemInfo. - */ - public static @NonNull List getNotificationsForItem( - @NonNull ItemInfo info, @NonNull List notifications) { - String shortcutId = ShortcutUtil.getShortcutIdIfPinnedShortcut(info); - if (shortcutId == null) { - return notifications; - } - 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 void dump(String prefix, PrintWriter writer) { writer.println(prefix + "PopupDataProvider:"); writer.println(prefix + "\tmPackageUserToDotInfos:" + mPackageUserToDotInfos); @@ -284,10 +252,6 @@ public class PopupDataProvider implements NotificationListener.NotificationsChan PopupDataChangeListener INSTANCE = new PopupDataChangeListener() { }; - default void onNotificationDotsUpdated(Predicate updatedDots) { } - - default void trimNotifications(Map updatedDots) { } - default void onWidgetsBound() { } /** A callback to get notified when recommended widgets are bound. */