summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/badge
diff options
context:
space:
mode:
authorTony Wickham <twickham@google.com>2017-01-20 09:38:25 -0800
committerTony Wickham <twickham@google.com>2017-01-25 17:36:31 -0800
commit9438ed414fdabadb4cd09da184867b1c44b91095 (patch)
tree9d84de236a89cde247b9de8f11408e815e6d6702 /src/com/android/launcher3/badge
parentf3d02e4716f89d14d9017851db9ad6141ad26875 (diff)
downloadandroid_packages_apps_Trebuchet-9438ed414fdabadb4cd09da184867b1c44b91095.tar.gz
android_packages_apps_Trebuchet-9438ed414fdabadb4cd09da184867b1c44b91095.tar.bz2
android_packages_apps_Trebuchet-9438ed414fdabadb4cd09da184867b1c44b91095.zip
Add swipe-to-dismiss notifications in popup menu.
- Next secondary icon animates up to replace dismissed main notification - Add padding around main notification so it always aligns with the straight edges of the view (not the rounded corners); looks more dismissable - Notification view collapses as notifications are dismissed - To mimic system notification behavior, we copy SwipeHelper, FlingAnimationUtils, and Interpolators. We also apply elevation to notifications and reveal a darker color beneath when dismissing. Bug: 32410600 Change-Id: I9fbf10e73bb4996f17ef061c856efb013967d972
Diffstat (limited to 'src/com/android/launcher3/badge')
-rw-r--r--src/com/android/launcher3/badge/BadgeInfo.java1
-rw-r--r--src/com/android/launcher3/badge/NotificationInfo.java82
-rw-r--r--src/com/android/launcher3/badge/NotificationListener.java213
3 files changed, 1 insertions, 295 deletions
diff --git a/src/com/android/launcher3/badge/BadgeInfo.java b/src/com/android/launcher3/badge/BadgeInfo.java
index 4255c5132..673c297dc 100644
--- a/src/com/android/launcher3/badge/BadgeInfo.java
+++ b/src/com/android/launcher3/badge/BadgeInfo.java
@@ -16,6 +16,7 @@
package com.android.launcher3.badge;
+import com.android.launcher3.notification.NotificationInfo;
import com.android.launcher3.util.PackageUserKey;
import java.util.HashSet;
diff --git a/src/com/android/launcher3/badge/NotificationInfo.java b/src/com/android/launcher3/badge/NotificationInfo.java
deleted file mode 100644
index 51f6a4f3a..000000000
--- a/src/com/android/launcher3/badge/NotificationInfo.java
+++ /dev/null
@@ -1,82 +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.badge;
-
-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.Launcher;
-import com.android.launcher3.popup.PopupContainerWithArrow;
-import com.android.launcher3.util.PackageUserKey;
-
-/**
- * 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 com.android.launcher3.badge.BadgeInfo} with only the notification key should
- * be passed around, and then this can be constructed using the StatusBarNotification from
- * {@link NotificationListener#getNotificationsForKeys(String[])}.
- */
-public class NotificationInfo implements View.OnClickListener {
-
- public final PackageUserKey packageUserKey;
- public final String notificationKey;
- public final CharSequence title;
- public final CharSequence text;
- public final Drawable iconDrawable;
- public final PendingIntent intent;
- public final boolean autoCancel;
-
- /**
- * Extracts the data that we need from the StatusBarNotification.
- */
- public NotificationInfo(Context context, StatusBarNotification notification) {
- packageUserKey = PackageUserKey.fromNotification(notification);
- notificationKey = notification.getKey();
- title = notification.getNotification().extras.getCharSequence(Notification.EXTRA_TITLE);
- text = notification.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT);
- Icon icon = notification.getNotification().getLargeIcon();
- if (icon == null) {
- icon = notification.getNotification().getSmallIcon();
- iconDrawable = icon.loadDrawable(context);
- iconDrawable.setTint(notification.getNotification().color);
- } else {
- iconDrawable = icon.loadDrawable(context);
- }
- intent = notification.getNotification().contentIntent;
- autoCancel = (notification.getNotification().flags
- & Notification.FLAG_AUTO_CANCEL) != 0;
- }
-
- @Override
- public void onClick(View view) {
- final Launcher launcher = Launcher.getLauncher(view.getContext());
- try {
- intent.send();
- } catch (PendingIntent.CanceledException e) {
- e.printStackTrace();
- }
- if (autoCancel) {
- launcher.getPopupDataProvider().cancelNotification(notificationKey);
- }
- PopupContainerWithArrow.getOpen(launcher).close(true);
- }
-}
diff --git a/src/com/android/launcher3/badge/NotificationListener.java b/src/com/android/launcher3/badge/NotificationListener.java
deleted file mode 100644
index 1668a6267..000000000
--- a/src/com/android/launcher3/badge/NotificationListener.java
+++ /dev/null
@@ -1,213 +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.badge;
-
-import android.app.Notification;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.service.notification.NotificationListenerService;
-import android.service.notification.StatusBarNotification;
-import android.support.annotation.Nullable;
-import android.support.v4.util.Pair;
-
-import com.android.launcher3.LauncherModel;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.util.PackageUserKey;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * A {@link NotificationListenerService} that sends updates to its
- * {@link NotificationsChangedListener} when notifications are posted or canceled,
- * as well and when this service first connects. An instance of NotificationListener,
- * and its methods for getting notifications, can be obtained via {@link #getInstance()}.
- */
-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 NotificationListener sNotificationListenerInstance = null;
- private static NotificationsChangedListener sNotificationsChangedListener;
-
- private final Handler mWorkerHandler;
- private final Handler mUiHandler;
-
- private Handler.Callback mWorkerCallback = new Handler.Callback() {
- @Override
- public boolean handleMessage(Message message) {
- switch (message.what) {
- case MSG_NOTIFICATION_POSTED:
- mUiHandler.obtainMessage(message.what, message.obj).sendToTarget();
- break;
- case MSG_NOTIFICATION_REMOVED:
- mUiHandler.obtainMessage(message.what, message.obj).sendToTarget();
- break;
- case MSG_NOTIFICATION_FULL_REFRESH:
- final List<StatusBarNotification> activeNotifications
- = filterNotifications(getActiveNotifications());
- mUiHandler.obtainMessage(message.what, activeNotifications).sendToTarget();
- break;
- }
- return true;
- }
- };
-
- private Handler.Callback mUiCallback = new Handler.Callback() {
- @Override
- public boolean handleMessage(Message message) {
- switch (message.what) {
- case MSG_NOTIFICATION_POSTED:
- if (sNotificationsChangedListener != null) {
- Pair<PackageUserKey, String> pair
- = (Pair<PackageUserKey, String>) message.obj;
- sNotificationsChangedListener.onNotificationPosted(pair.first, pair.second);
- }
- break;
- case MSG_NOTIFICATION_REMOVED:
- if (sNotificationsChangedListener != null) {
- Pair<PackageUserKey, String> pair
- = (Pair<PackageUserKey, String>) message.obj;
- sNotificationsChangedListener.onNotificationRemoved(pair.first, pair.second);
- }
- break;
- case MSG_NOTIFICATION_FULL_REFRESH:
- if (sNotificationsChangedListener != null) {
- sNotificationsChangedListener.onNotificationFullRefresh(
- (List<StatusBarNotification>) message.obj);
- }
- break;
- }
- return true;
- }
- };
-
- public NotificationListener() {
- super();
- mWorkerHandler = new Handler(LauncherModel.getWorkerLooper(), mWorkerCallback);
- mUiHandler = new Handler(Looper.getMainLooper(), mUiCallback);
- }
-
- public static @Nullable NotificationListener getInstance() {
- return sNotificationListenerInstance;
- }
-
- public static void setNotificationsChangedListener(NotificationsChangedListener listener) {
- if (!FeatureFlags.BADGE_ICONS) {
- return;
- }
- sNotificationsChangedListener = listener;
-
- NotificationListener notificationListener = getInstance();
- if (notificationListener != null) {
- notificationListener.onNotificationFullRefresh();
- }
- }
-
- public static void removeNotificationsChangedListener() {
- sNotificationsChangedListener = null;
- }
-
- @Override
- public void onListenerConnected() {
- super.onListenerConnected();
- sNotificationListenerInstance = this;
- onNotificationFullRefresh();
- }
-
- private void onNotificationFullRefresh() {
- mWorkerHandler.obtainMessage(MSG_NOTIFICATION_FULL_REFRESH).sendToTarget();
- }
-
- @Override
- public void onListenerDisconnected() {
- super.onListenerDisconnected();
- sNotificationListenerInstance = null;
- }
-
- @Override
- public void onNotificationPosted(final StatusBarNotification sbn) {
- super.onNotificationPosted(sbn);
- if (!shouldBeFilteredOut(sbn.getNotification())) {
- Pair<PackageUserKey, String> packageUserKeyAndNotificationKey
- = new Pair<>(PackageUserKey.fromNotification(sbn), sbn.getKey());
- mWorkerHandler.obtainMessage(MSG_NOTIFICATION_POSTED, packageUserKeyAndNotificationKey)
- .sendToTarget();
- }
- }
-
- @Override
- public void onNotificationRemoved(final StatusBarNotification sbn) {
- super.onNotificationRemoved(sbn);
- if (!shouldBeFilteredOut(sbn.getNotification())) {
- Pair<PackageUserKey, String> packageUserKeyAndNotificationKey
- = new Pair<>(PackageUserKey.fromNotification(sbn), sbn.getKey());
- mWorkerHandler.obtainMessage(MSG_NOTIFICATION_REMOVED, packageUserKeyAndNotificationKey)
- .sendToTarget();
- }
- }
-
- /** This makes a potentially expensive binder call and should be run on a background thread. */
- public List<StatusBarNotification> getNotificationsForKeys(String[] keys) {
- StatusBarNotification[] notifications = NotificationListener.this
- .getActiveNotifications(keys);
- return notifications == null ? Collections.EMPTY_LIST : Arrays.asList(notifications);
- }
-
- /**
- * Filter out notifications that don't have an intent
- * or are headers for grouped notifications.
- *
- * TODO: use the system concept of a badged notification instead
- */
- private List<StatusBarNotification> filterNotifications(
- StatusBarNotification[] notifications) {
- if (notifications == null) return null;
- Set<Integer> removedNotifications = new HashSet<>();
- for (int i = 0; i < notifications.length; i++) {
- if (shouldBeFilteredOut(notifications[i].getNotification())) {
- removedNotifications.add(i);
- }
- }
- List<StatusBarNotification> filteredNotifications = new ArrayList<>(
- notifications.length - removedNotifications.size());
- for (int i = 0; i < notifications.length; i++) {
- if (!removedNotifications.contains(i)) {
- filteredNotifications.add(notifications[i]);
- }
- }
- return filteredNotifications;
- }
-
- private boolean shouldBeFilteredOut(Notification notification) {
- boolean isGroupHeader = (notification.flags & Notification.FLAG_GROUP_SUMMARY) != 0;
- return (notification.contentIntent == null || isGroupHeader);
- }
-
- public interface NotificationsChangedListener {
- void onNotificationPosted(PackageUserKey postedPackageUserKey, String notificationKey);
- void onNotificationRemoved(PackageUserKey removedPackageUserKey, String notificationKey);
- void onNotificationFullRefresh(List<StatusBarNotification> activeNotifications);
- }
-}