OSDN Git Service

Manage heads up state during notification update.
authorChris Wren <cwren@android.com>
Wed, 11 Jun 2014 21:37:28 +0000 (17:37 -0400)
committerChris Wren <cwren@android.com>
Thu, 12 Jun 2014 03:53:30 +0000 (23:53 -0400)
Notifications can now get the heads up slot on updates.
FLAG_ONLY_ALERT_ONCE suppresses this behavior.

Bug: 15534198
Change-Id: Ie27b7c7d93c590d777670c538fb796a04252046f

packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java

index 5a9fe91..7196b62 100644 (file)
@@ -311,7 +311,8 @@ public abstract class BaseStatusBar extends SystemUI implements
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    if (mNotificationData.findByKey(sbn.getKey()) != null) {
+                    if (mNotificationData.findByKey(sbn.getKey()) != null ||
+                            isHeadsUp(sbn.getKey())) {
                         updateNotificationInternal(sbn, rankingMap);
                     } else {
                         addNotificationInternal(sbn, rankingMap);
@@ -467,6 +468,10 @@ public abstract class BaseStatusBar extends SystemUI implements
         // should be overridden
     }
 
+    public boolean isHeadsUp(String key) {
+      return mHeadsUpNotificationView != null && mHeadsUpNotificationView.isShowing(key);
+    }
+
     public boolean notificationIsForCurrentProfiles(StatusBarNotification n) {
         final int thisUserId = mCurrentUserId;
         final int notificationUserId = n.getUserId();
@@ -892,10 +897,7 @@ public abstract class BaseStatusBar extends SystemUI implements
     }
 
     public boolean inflateViews(NotificationData.Entry entry, ViewGroup parent, boolean isHeadsUp) {
-        int minHeight =
-                mContext.getResources().getDimensionPixelSize(R.dimen.notification_min_height);
-        int maxHeight =
-                mContext.getResources().getDimensionPixelSize(R.dimen.notification_max_height);
+        int maxHeight = mRowMaxHeight;
         StatusBarNotification sbn = entry.notification;
         RemoteViews contentView = sbn.getNotification().contentView;
         RemoteViews bigContentView = sbn.getNotification().bigContentView;
@@ -1058,7 +1060,7 @@ public abstract class BaseStatusBar extends SystemUI implements
             }
         }
         entry.row = row;
-        entry.row.setHeightRange(mRowMinHeight, mRowMaxHeight);
+        entry.row.setHeightRange(mRowMinHeight, maxHeight);
         entry.row.setOnActivatedListener(this);
         entry.row.setIsBelowSpeedBump(isBelowSpeedBump(entry.notification));
         entry.expanded = contentViewLocal;
@@ -1333,9 +1335,15 @@ public abstract class BaseStatusBar extends SystemUI implements
     public void updateNotificationInternal(StatusBarNotification notification, RankingMap ranking) {
         if (DEBUG) Log.d(TAG, "updateNotification(" + notification + ")");
 
-        final NotificationData.Entry oldEntry = mNotificationData.findByKey(notification.getKey());
+        final String key = notification.getKey();
+        boolean wasHeadsUp = isHeadsUp(key);
+        NotificationData.Entry oldEntry;
+        if (wasHeadsUp) {
+            oldEntry = mHeadsUpNotificationView.getEntry();
+        } else {
+            oldEntry = mNotificationData.findByKey(key);
+        }
         if (oldEntry == null) {
-            Log.w(TAG, "updateNotification for unknown key: " + notification.getKey());
             return;
         }
 
@@ -1401,39 +1409,49 @@ public abstract class BaseStatusBar extends SystemUI implements
                         && oldPublicContentView.getPackage() != null
                         && oldPublicContentView.getPackage().equals(publicContentView.getPackage())
                         && oldPublicContentView.getLayoutId() == publicContentView.getLayoutId());
-
-
         boolean updateTicker = notification.getNotification().tickerText != null
                 && !TextUtils.equals(notification.getNotification().tickerText,
                 oldEntry.notification.getNotification().tickerText);
+
         if (contentsUnchanged && bigContentsUnchanged && headsUpContentsUnchanged
                 && publicUnchanged) {
-            if (DEBUG) Log.d(TAG, "reusing notification for key: " + notification.getKey());
+            if (DEBUG) Log.d(TAG, "reusing notification for key: " + key);
             oldEntry.notification = notification;
             try {
-                updateNotificationViews(oldEntry, notification);
-
-                if (ENABLE_HEADS_UP && mHeadsUpNotificationView.getEntry() != null
-                        && oldNotification == mHeadsUpNotificationView.getEntry().notification) {
-                    if (!shouldInterrupt(notification)) {
-                        if (DEBUG) Log.d(TAG, "no longer interrupts!");
-                        scheduleHeadsUpClose();
-                    } else {
-                        if (DEBUG) Log.d(TAG, "updating the current heads up:" + notification);
-                        mHeadsUpNotificationView.getEntry().notification = notification;
-                        updateHeadsUpViews(mHeadsUpNotificationView.getEntry(), notification);
+                if (oldEntry.icon != null) {
+                    // Update the icon
+                    final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
+                            notification.getUser(),
+                            notification.getNotification().icon,
+                            notification.getNotification().iconLevel,
+                            notification.getNotification().number,
+                            notification.getNotification().tickerText);
+                    if (!oldEntry.icon.set(ic)) {
+                        handleNotificationError(notification, "Couldn't update icon: " + ic);
+                        return;
                     }
                 }
 
-                // Update the icon.
-                final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
-                        notification.getUser(),
-                        notification.getNotification().icon, notification.getNotification().iconLevel,
-                        notification.getNotification().number,
-                        notification.getNotification().tickerText);
-                if (!oldEntry.icon.set(ic)) {
-                    handleNotificationError(notification, "Couldn't update icon: " + ic);
-                    return;
+                final boolean shouldInterrupt = shouldInterrupt(notification);
+                final boolean alertAgain = alertAgain(oldEntry);
+                if (wasHeadsUp) {
+                    if (shouldInterrupt) {
+                        updateHeadsUpViews(oldEntry, notification);
+                        if (alertAgain) {
+                            resetHeadsUpDecayTimer();
+                        }
+                    } else {
+                        // we updated the notification above, so release to build a new shade entry
+                        mHeadsUpNotificationView.releaseAndClose();
+                        return;
+                    }
+                } else {
+                    if (shouldInterrupt && alertAgain) {
+                        removeNotificationViews(key, ranking);
+                        addNotificationInternal(notification, ranking);  //this will pop the headsup
+                    } else {
+                        updateNotificationViews(oldEntry, notification);
+                    }
                 }
                 mNotificationData.updateRanking(ranking);
                 updateNotifications();
@@ -1441,16 +1459,15 @@ public abstract class BaseStatusBar extends SystemUI implements
             catch (RuntimeException e) {
                 // It failed to add cleanly.  Log, and remove the view from the panel.
                 Log.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
-                removeNotificationViews(notification.getKey(), ranking);
+                removeNotificationViews(key, ranking);
                 addNotificationViews(notification, ranking);
             }
         } else {
-            if (DEBUG) Log.d(TAG, "not reusing notification for key: " + notification.getKey());
+            if (DEBUG) Log.d(TAG, "not reusing notification for key: " + key);
             if (DEBUG) Log.d(TAG, "contents was " + (contentsUnchanged ? "unchanged" : "changed"));
-            removeNotificationViews(notification.getKey(), ranking);
-            addNotificationViews(notification, ranking);  // will also replace the heads up
-            final NotificationData.Entry newEntry = mNotificationData.findByKey(
-                    notification.getKey());
+            removeNotificationViews(key, ranking);
+            addNotificationViews(notification, ranking);
+            final NotificationData.Entry newEntry = mNotificationData.findByKey(key);
             final boolean userChangedExpansion = oldEntry.row.hasUserChangedExpansion();
             if (userChangedExpansion) {
                 boolean userExpanded = oldEntry.row.isUserExpanded();
@@ -1535,6 +1552,12 @@ public abstract class BaseStatusBar extends SystemUI implements
         }
     }
 
+    private boolean alertAgain(Entry entry) {
+        final StatusBarNotification sbn = entry.notification;
+        return entry == null || !entry.hasInterrupted()
+                || (sbn.getNotification().flags & Notification.FLAG_ONLY_ALERT_ONCE) == 0;
+    }
+
     protected boolean shouldInterrupt(StatusBarNotification sbn) {
         Notification notification = sbn.getNotification();
         // some predicates to make the boolean logic legible
index c313c58..9921c55 100644 (file)
@@ -68,6 +68,10 @@ public class NotificationData {
         public void setInterruption() {
             interruption = true;
         }
+
+        public boolean hasInterrupted() {
+            return interruption;
+        }
     }
 
     private final ArrayList<Entry> mEntries = new ArrayList<Entry>();
index d778ccb..0f6c4b2 100644 (file)
@@ -101,6 +101,8 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
             mSwipeHelper.snapChild(mContentHolder, 1f);
             mStartTouchTime = System.currentTimeMillis() + mTouchSensitivityDelay;
 
+            mHeadsUp.setInterruption();
+
             // 2. Animate mHeadsUpNotificationView in
             mBar.scheduleHeadsUpOpen();
 
@@ -110,6 +112,10 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
         return true;
     }
 
+    public boolean isShowing(String key) {
+        return mHeadsUp != null && mHeadsUp.key.equals(key);
+    }
+
     /** Discard the Heads Up notification. */
     public void clear() {
         mHeadsUp = null;
@@ -136,6 +142,11 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
         mHeadsUp = null;
     }
 
+    public void releaseAndClose() {
+        release();
+        mBar.scheduleHeadsUpClose();
+    }
+
     public NotificationData.Entry getEntry() {
         return mHeadsUp;
     }
@@ -378,4 +389,4 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
             return mConsuming;
         }
     }
-}
\ No newline at end of file
+}