diff options
4 files changed, 151 insertions, 64 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index a7af99819289..4ed417747221 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -80,11 +80,10 @@ import com.android.systemui.SearchPanelView; import com.android.systemui.SystemUI; import com.android.systemui.statusbar.NotificationData.Entry; import com.android.systemui.statusbar.phone.KeyguardTouchDelegate; +import com.android.systemui.statusbar.policy.HeadsUpNotificationView; import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import java.util.Locale; import static com.android.keyguard.KeyguardHostView.OnDismissAction; @@ -106,6 +105,7 @@ public abstract class BaseStatusBar extends SystemUI implements protected static final int MSG_SHOW_HEADS_UP = 1026; protected static final int MSG_HIDE_HEADS_UP = 1027; protected static final int MSG_ESCALATE_HEADS_UP = 1028; + protected static final int MSG_DECAY_HEADS_UP = 1029; protected static final boolean ENABLE_HEADS_UP = true; // scores above this threshold should be displayed in heads up mode. @@ -129,7 +129,9 @@ public abstract class BaseStatusBar extends SystemUI implements protected NotificationData mNotificationData = new NotificationData(); protected NotificationStackScrollLayout mStackScroller; - protected NotificationData.Entry mInterruptingNotificationEntry; + // for heads up notifications + protected HeadsUpNotificationView mHeadsUpNotificationView; + protected int mHeadsUpNotificationDecay; protected long mInterruptingNotificationTime; // used to notify status bar for suppressing notification LED @@ -505,8 +507,8 @@ public abstract class BaseStatusBar extends SystemUI implements protected View updateNotificationVetoButton(View row, StatusBarNotification n) { View vetoButton = row.findViewById(R.id.veto); - if (n.isClearable() || (mInterruptingNotificationEntry != null - && mInterruptingNotificationEntry.row == row)) { + if (n.isClearable() || (mHeadsUpNotificationView.getEntry() != null + && mHeadsUpNotificationView.getEntry().row == row)) { final String _pkg = n.getPackageName(); final String _tag = n.getTag(); final int _id = n.getId(); @@ -766,6 +768,12 @@ public abstract class BaseStatusBar extends SystemUI implements public abstract void resetHeadsUpDecayTimer(); + public abstract void scheduleHeadsUpOpen(); + + public abstract void scheduleHeadsUpClose(); + + public abstract void scheduleHeadsUpEscalation(); + /** * Save the current "public" (locked and secure) state of the lockscreen. */ @@ -797,6 +805,18 @@ public abstract class BaseStatusBar extends SystemUI implements return mUsersAllowingPrivateNotifications.get(userHandle); } + public void onNotificationClear(StatusBarNotification notification) { + try { + mBarService.onNotificationClear( + notification.getPackageName(), + notification.getTag(), + notification.getId(), + notification.getUserId()); + } catch (android.os.RemoteException ex) { + // oh well + } + } + protected class H extends Handler { public void handleMessage(Message m) { Intent intent; @@ -1101,7 +1121,7 @@ public abstract class BaseStatusBar extends SystemUI implements try { if (mIsHeadsUp) { - mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP); + mHeadsUpNotificationView.clear(); } mBarService.onNotificationClick(mNotificationKey); } catch (RemoteException ex) { @@ -1394,15 +1414,15 @@ public abstract class BaseStatusBar extends SystemUI implements try { updateNotificationViews(oldEntry, notification); - if (ENABLE_HEADS_UP && mInterruptingNotificationEntry != null - && oldNotification == mInterruptingNotificationEntry.notification) { + if (ENABLE_HEADS_UP && mHeadsUpNotificationView.getEntry() != null + && oldNotification == mHeadsUpNotificationView.getEntry().notification) { if (!shouldInterrupt(notification)) { if (DEBUG) Log.d(TAG, "no longer interrupts!"); - mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP); + scheduleHeadsUpClose(); } else { if (DEBUG) Log.d(TAG, "updating the current heads up:" + notification); - mInterruptingNotificationEntry.notification = notification; - updateHeadsUpViews(mInterruptingNotificationEntry, notification); + mHeadsUpNotificationView.getEntry().notification = notification; + updateHeadsUpViews(mHeadsUpNotificationView.getEntry(), notification); } } @@ -1511,8 +1531,8 @@ public abstract class BaseStatusBar extends SystemUI implements } protected void notifyHeadsUpScreenOn(boolean screenOn) { - if (!screenOn && mInterruptingNotificationEntry != null) { - mHandler.sendEmptyMessage(MSG_ESCALATE_HEADS_UP); + if (!screenOn) { + scheduleHeadsUpEscalation(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 4749b9ce3a97..4e34a3cc3431 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -278,10 +278,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // the date view DateView mDateView; - // for heads up notifications - private HeadsUpNotificationView mHeadsUpNotificationView; - private int mHeadsUpNotificationDecay; - // on-screen navigation buttons private NavigationBarView mNavigationBarView = null; private int mNavigationBarWindowState = WINDOW_STATE_SHOWING; @@ -367,7 +363,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (!mUseHeadsUp) { Log.d(TAG, "dismissing any existing heads up notification on disable event"); setHeadsUpVisibility(false); - mHeadsUpNotificationView.setNotification(null); + mHeadsUpNotificationView.release(); removeHeadsUpView(); } else { addHeadsUpView(); @@ -1076,29 +1072,27 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void displayNotification(StatusBarNotification notification, Ranking ranking) { - Entry shadeEntry = createNotificationViews(notification); - if (shadeEntry == null) { - return; - } if (mUseHeadsUp && shouldInterrupt(notification)) { if (DEBUG) Log.d(TAG, "launching notification in heads up mode"); Entry interruptionCandidate = new Entry(notification, null); ViewGroup holder = mHeadsUpNotificationView.getHolder(); if (inflateViewsForHeadsUp(interruptionCandidate, holder)) { mInterruptingNotificationTime = System.currentTimeMillis(); - mInterruptingNotificationEntry = interruptionCandidate; - shadeEntry.setInterruption(); // 1. Populate mHeadsUpNotificationView - mHeadsUpNotificationView.setNotification(mInterruptingNotificationEntry); - - // 2. Animate mHeadsUpNotificationView in - mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP); + mHeadsUpNotificationView.showNotification(interruptionCandidate); - // 3. Set alarm to age the notification off - resetHeadsUpDecayTimer(); + // do not show the notification in the shade, yet. + return; } - } else if (notification.getNotification().fullScreenIntent != null) { + } + + Entry shadeEntry = createNotificationViews(notification); + if (shadeEntry == null) { + return; + } + + if (notification.getNotification().fullScreenIntent != null) { // Stop screensaver if the notification has a full-screen intent. // (like an incoming phone call) awakenDreams(); @@ -1113,7 +1107,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // usual case: status bar visible & not immersive // show the ticker if there isn't already a heads up - if (mInterruptingNotificationEntry == null) { + if (mHeadsUpNotificationView.getEntry() == null) { tick(notification, true); } } @@ -1123,16 +1117,44 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, updateExpandedViewPos(EXPANDED_LEAVE_ALONE); } + public void displayNotificationFromHeadsUp(StatusBarNotification notification) { + NotificationData.Entry shadeEntry = createNotificationViews(notification); + if (shadeEntry == null) { + return; + } + shadeEntry.setInterruption(); + + addNotificationViews(shadeEntry, null); + // Recalculate the position of the sliding windows and the titles. + setAreThereNotifications(); + updateExpandedViewPos(EXPANDED_LEAVE_ALONE); + } + @Override public void resetHeadsUpDecayTimer() { - mHandler.removeMessages(MSG_HIDE_HEADS_UP); + mHandler.removeMessages(MSG_DECAY_HEADS_UP); if (mUseHeadsUp && mHeadsUpNotificationDecay > 0 && mHeadsUpNotificationView.isClearable()) { - mHandler.sendEmptyMessageDelayed(MSG_HIDE_HEADS_UP, mHeadsUpNotificationDecay); + mHandler.sendEmptyMessageDelayed(MSG_DECAY_HEADS_UP, mHeadsUpNotificationDecay); } } @Override + public void scheduleHeadsUpOpen() { + mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP); + } + + @Override + public void scheduleHeadsUpClose() { + mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP); + } + + @Override + public void scheduleHeadsUpEscalation() { + mHandler.sendEmptyMessage(MSG_ESCALATE_HEADS_UP); + } + + @Override public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) { super.updateNotificationInternal(notification, ranking); // if we're here, then the notification is already in the shade @@ -1148,6 +1170,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, @Override public void removeNotificationInternal(String key, Ranking ranking) { + if (ENABLE_HEADS_UP && mHeadsUpNotificationView.getEntry() != null + && key.equals(mHeadsUpNotificationView.getEntry().notification.getKey())) { + mHeadsUpNotificationView.clear(); + } + StatusBarNotification old = removeNotificationViews(key, ranking); if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old); @@ -1160,11 +1187,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // Recalculate the position of the sliding windows and the titles. updateExpandedViewPos(EXPANDED_LEAVE_ALONE); - if (ENABLE_HEADS_UP && mInterruptingNotificationEntry != null - && old == mInterruptingNotificationEntry.notification) { - mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP); - } - if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0 && !mNotificationPanel.isTracking() && mState != StatusBarState.KEYGUARD) { animateCollapsePanels(); @@ -1574,7 +1596,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, case MSG_SHOW_HEADS_UP: setHeadsUpVisibility(true); break; + case MSG_DECAY_HEADS_UP: + mHeadsUpNotificationView.release(); + setHeadsUpVisibility(false); + break; case MSG_HIDE_HEADS_UP: + mHeadsUpNotificationView.release(); setHeadsUpVisibility(false); break; case MSG_ESCALATE_HEADS_UP: @@ -1587,8 +1614,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, /** if the interrupting notification had a fullscreen intent, fire it now. */ private void escalateHeadsUp() { - if (mInterruptingNotificationEntry != null) { - final StatusBarNotification sbn = mInterruptingNotificationEntry.notification; + if (mHeadsUpNotificationView.getEntry() != null) { + final StatusBarNotification sbn = mHeadsUpNotificationView.getEntry().notification; + mHeadsUpNotificationView.release(); final Notification notification = sbn.getNotification(); if (notification.fullScreenIntent != null) { if (DEBUG) @@ -2243,7 +2271,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, pw.print(" mUseHeadsUp="); pw.println(mUseHeadsUp); pw.print(" interrupting package: "); - pw.println(hunStateToString(mInterruptingNotificationEntry)); + pw.println(hunStateToString(mHeadsUpNotificationView.getEntry())); dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions()); if (mNavigationBarView != null) { pw.print(" mNavigationBarWindowState="); @@ -2517,26 +2545,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (!ENABLE_HEADS_UP) return; if (DEBUG) Log.v(TAG, (vis ? "showing" : "hiding") + " heads up window"); mHeadsUpNotificationView.setVisibility(vis ? View.VISIBLE : View.GONE); - if (!vis) { - if (DEBUG) Log.d(TAG, "setting heads up entry to null"); - mInterruptingNotificationEntry = null; - } } public void onHeadsUpDismissed() { - if (mInterruptingNotificationEntry == null) return; - mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP); - if (mHeadsUpNotificationView.isClearable()) { - try { - mBarService.onNotificationClear( - mInterruptingNotificationEntry.notification.getPackageName(), - mInterruptingNotificationEntry.notification.getTag(), - mInterruptingNotificationEntry.notification.getId(), - mInterruptingNotificationEntry.notification.getUserId()); - } catch (android.os.RemoteException ex) { - // oh well - } - } + mHeadsUpNotificationView.dismiss(); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java index df01c12c2098..d778ccb4b7cf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java @@ -33,9 +33,9 @@ import com.android.systemui.ExpandHelper; import com.android.systemui.Gefingerpoken; import com.android.systemui.R; import com.android.systemui.SwipeHelper; -import com.android.systemui.statusbar.BaseStatusBar; import com.android.systemui.statusbar.ExpandableView; import com.android.systemui.statusbar.NotificationData; +import com.android.systemui.statusbar.phone.PhoneStatusBar; public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.Callback, ExpandHelper.Callback, ViewTreeObserver.OnComputeInternalInsetsListener { @@ -51,7 +51,7 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. private SwipeHelper mSwipeHelper; private EdgeSwipeHelper mEdgeSwipeHelper; - private BaseStatusBar mBar; + private PhoneStatusBar mBar; private ExpandHelper mExpandHelper; private long mStartTouchTime; @@ -69,7 +69,7 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. if (DEBUG) Log.v(TAG, "create() " + mTouchSensitivityDelay); } - public void setBar(BaseStatusBar bar) { + public void setBar(PhoneStatusBar bar) { mBar = bar; } @@ -77,7 +77,10 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. return mContentHolder; } - public boolean setNotification(NotificationData.Entry headsUp) { + public boolean showNotification(NotificationData.Entry headsUp) { + // bump any previous heads up back to the shade + release(); + mHeadsUp = headsUp; if (mContentHolder != null) { mContentHolder.removeAllViews(); @@ -97,10 +100,46 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. mSwipeHelper.snapChild(mContentHolder, 1f); mStartTouchTime = System.currentTimeMillis() + mTouchSensitivityDelay; + + // 2. Animate mHeadsUpNotificationView in + mBar.scheduleHeadsUpOpen(); + + // 3. Set alarm to age the notification off + mBar.resetHeadsUpDecayTimer(); } return true; } + /** Discard the Heads Up notification. */ + public void clear() { + mHeadsUp = null; + mBar.scheduleHeadsUpClose(); + } + + /** Respond to dismissal of the Heads Up window. */ + public void dismiss() { + if (mHeadsUp == null) return; + if (mHeadsUp.notification.isClearable()) { + mBar.onNotificationClear(mHeadsUp.notification); + } else { + release(); + } + mHeadsUp = null; + mBar.scheduleHeadsUpClose(); + } + + /** Push any current Heads Up notification down into the shade. */ + public void release() { + if (mHeadsUp != null) { + mBar.displayNotificationFromHeadsUp(mHeadsUp.notification); + } + mHeadsUp = null; + } + + public NotificationData.Entry getEntry() { + return mHeadsUp; + } + public boolean isClearable() { return mHeadsUp == null || mHeadsUp.notification.isClearable(); } @@ -125,7 +164,7 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. if (mHeadsUp != null) { // whoops, we're on already! - setNotification(mHeadsUp); + showNotification(mHeadsUp); } getViewTreeObserver().addOnComputeInternalInsetsListener(this); @@ -282,6 +321,10 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. mTmpTwoArray[1] + mContentHolder.getHeight()); } + public void escalate() { + mBar.scheduleHeadsUpEscalation(); + } + private class EdgeSwipeHelper implements Gefingerpoken { private static final boolean DEBUG_EDGE_SWIPE = false; private final float mTouchSlop; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java index faea8de51bb8..aa8373db0cb8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java @@ -147,6 +147,18 @@ public class TvStatusBar extends BaseStatusBar { } @Override + public void scheduleHeadsUpOpen() { + } + + @Override + public void scheduleHeadsUpEscalation() { + } + + @Override + public void scheduleHeadsUpClose() { + } + + @Override protected int getMaxKeyguardNotifications() { return 0; } |