5656import android .view .MotionEvent ;
5757import android .view .VelocityTracker ;
5858import android .view .View ;
59+ import android .view .ViewConfiguration ;
5960import android .view .ViewGroup ;
6061import android .view .ViewGroup .LayoutParams ;
6162import android .view .Window ;
7778import com .android .internal .statusbar .StatusBarNotification ;
7879
7980import com .android .systemui .R ;
81+ import com .android .systemui .SwipeHelper ;
8082import com .android .systemui .recent .RecentTasksLoader ;
8183import com .android .systemui .recent .RecentsPanelView ;
8284import com .android .systemui .recent .TaskDescription ;
8688import com .android .systemui .statusbar .SignalClusterView ;
8789import com .android .systemui .statusbar .policy .DateView ;
8890import com .android .systemui .statusbar .policy .BatteryController ;
91+ import com .android .systemui .statusbar .policy .IntruderAlertView ;
8992import com .android .systemui .statusbar .policy .LocationController ;
9093import com .android .systemui .statusbar .policy .NetworkController ;
9194import com .android .systemui .statusbar .policy .NotificationRowLayout ;
@@ -102,7 +105,7 @@ public class PhoneStatusBar extends BaseStatusBar {
102105 public static final String ACTION_STATUSBAR_START
103106 = "com.android.internal.policy.statusbar.START" ;
104107
105- private static final boolean ENABLE_INTRUDERS = false ;
108+ private static final boolean ENABLE_INTRUDERS = true ;
106109
107110 static final int EXPANDED_LEAVE_ALONE = -10000 ;
108111 static final int EXPANDED_FULL_OPEN = -10001 ;
@@ -117,7 +120,7 @@ public class PhoneStatusBar extends BaseStatusBar {
117120 private static final int MSG_CLOSE_RECENTS_PANEL = 1021 ;
118121
119122 // will likely move to a resource or other tunable param at some point
120- private static final int INTRUDER_ALERT_DECAY_MS = 10000 ;
123+ private static final int INTRUDER_ALERT_DECAY_MS = 0 ; // disabled, was 10000;
121124
122125 private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true ;
123126
@@ -185,7 +188,7 @@ public class PhoneStatusBar extends BaseStatusBar {
185188 DateView mDateView ;
186189
187190 // for immersive activities
188- private View mIntruderAlertView ;
191+ private IntruderAlertView mIntruderAlertView ;
189192
190193 // on-screen navigation buttons
191194 private NavigationBarView mNavigationBarView = null ;
@@ -294,9 +297,9 @@ protected View makeStatusBarView() {
294297 }
295298 mNotificationPanel = expanded .findViewById (R .id .notification_panel );
296299
297- mIntruderAlertView = View .inflate (context , R .layout .intruder_alert , null );
300+ mIntruderAlertView = ( IntruderAlertView ) View .inflate (context , R .layout .intruder_alert , null );
298301 mIntruderAlertView .setVisibility (View .GONE );
299- mIntruderAlertView .setClickable ( true );
302+ mIntruderAlertView .setBar ( this );
300303
301304 PhoneStatusBarView sb = (PhoneStatusBarView )View .inflate (context ,
302305 R .layout .status_bar , null );
@@ -455,6 +458,7 @@ public void onClick(View v) {
455458 toggleRecentApps ();
456459 }
457460 };
461+ private StatusBarNotification mCurrentlyIntrudingNotification ;
458462
459463 private void prepareNavigationBarView () {
460464 mNavigationBarView .reorient ();
@@ -510,7 +514,7 @@ private void addIntruderView() {
510514 WindowManager .LayoutParams lp = new WindowManager .LayoutParams (
511515 ViewGroup .LayoutParams .MATCH_PARENT ,
512516 ViewGroup .LayoutParams .WRAP_CONTENT ,
513- WindowManager .LayoutParams .TYPE_STATUS_BAR_SUB_PANEL ,
517+ WindowManager .LayoutParams .TYPE_STATUS_BAR_PANEL , // above the status bar!
514518 WindowManager .LayoutParams .FLAG_LAYOUT_IN_SCREEN
515519 | WindowManager .LayoutParams .FLAG_LAYOUT_NO_LIMITS
516520 | WindowManager .LayoutParams .FLAG_NOT_TOUCH_MODAL
@@ -519,7 +523,7 @@ private void addIntruderView() {
519523 | WindowManager .LayoutParams .FLAG_SPLIT_TOUCH ,
520524 PixelFormat .TRANSLUCENT );
521525 lp .gravity = Gravity .TOP | Gravity .FILL_HORIZONTAL ;
522- lp .y += height * 1.5 ; // FIXME
526+ // lp.y += height * 1.5; // FIXME
523527 lp .setTitle ("IntruderAlert" );
524528 lp .packageName = mContext .getPackageName ();
525529 lp .windowAnimations = R .style .Animation_StatusBar_IntruderAlert ;
@@ -562,30 +566,39 @@ public void addNotification(IBinder key, StatusBarNotification notification) {
562566 } catch (RemoteException ex ) {
563567 }
564568 if (ENABLE_INTRUDERS && (
565- (notification .score >= mIntruderInImmersiveMinScore )
566- || (!immersive && (notification .score > mIntruderMinScore )))) {
569+ // TODO(dsandler): Only if the screen is on
570+ notification .notification .intruderView != null )) {
571+ // notification.notification.fullScreenIntent != null
572+ // || (notification.score >= mIntruderInImmersiveMinScore)
573+ // || (!immersive && (notification.score > mIntruderMinScore)))) {
567574 Slog .d (TAG , "Presenting high-priority notification" );
568575 // special new transient ticker mode
569576 // 1. Populate mIntruderAlertView
577+
578+ if (notification .notification .intruderView == null ) {
579+ Slog .e (TAG , notification .notification .toString () + " wanted to intrude but intruderView was null" );
580+ return ;
581+ }
570582
571- ImageView alertIcon = ( ImageView ) mIntruderAlertView . findViewById ( R . id . alertIcon );
572- TextView alertText = ( TextView ) mIntruderAlertView . findViewById ( R . id . alertText ) ;
573- alertIcon . setImageDrawable ( StatusBarIconView . getIcon (
574- alertIcon . getContext () ,
575- iconView . getStatusBarIcon ()));
576- alertText . setText ( notification . notification . tickerText ) ;
583+ // bind the click event to the content area
584+ PendingIntent contentIntent = notification . notification . contentIntent ;
585+ final View . OnClickListener listener = ( contentIntent != null )
586+ ? new NotificationClicker ( contentIntent ,
587+ notification . pkg , notification . tag , notification . id )
588+ : null ;
577589
578- View button = mIntruderAlertView .findViewById (R .id .intruder_alert_content );
579- button .setOnClickListener (
580- new NotificationClicker (notification .notification .contentIntent ,
581- notification .pkg , notification .tag , notification .id ));
590+ mIntruderAlertView .applyIntruderContent (notification .notification .intruderView , listener );
582591
592+ mCurrentlyIntrudingNotification = notification ;
593+
583594 // 2. Animate mIntruderAlertView in
584595 mHandler .sendEmptyMessage (MSG_SHOW_INTRUDER );
585596
586597 // 3. Set alarm to age the notification off (TODO)
587598 mHandler .removeMessages (MSG_HIDE_INTRUDER );
588- mHandler .sendEmptyMessageDelayed (MSG_HIDE_INTRUDER , INTRUDER_ALERT_DECAY_MS );
599+ if (INTRUDER_ALERT_DECAY_MS > 0 ) {
600+ mHandler .sendEmptyMessageDelayed (MSG_HIDE_INTRUDER , INTRUDER_ALERT_DECAY_MS );
601+ }
589602 } else if (notification .notification .fullScreenIntent != null ) {
590603 // not immersive & a full-screen alert should be shown
591604 Slog .d (TAG , "Notification has fullScreenIntent; sending fullScreenIntent" );
@@ -596,8 +609,10 @@ public void addNotification(IBinder key, StatusBarNotification notification) {
596609 } else {
597610 // usual case: status bar visible & not immersive
598611
599- // show the ticker
600- tick (notification );
612+ // show the ticker if there isn't an intruder too
613+ if (mCurrentlyIntrudingNotification == null ) {
614+ tick (notification );
615+ }
601616 }
602617
603618 // Recalculate the position of the sliding windows and the titles.
@@ -708,18 +723,33 @@ public void updateNotification(IBinder key, StatusBarNotification notification)
708723 // Recalculate the position of the sliding windows and the titles.
709724 setAreThereNotifications ();
710725 updateExpandedViewPos (EXPANDED_LEAVE_ALONE );
726+
727+ // See if we need to update the intruder.
728+ if (oldNotification == mCurrentlyIntrudingNotification ) {
729+ if (DEBUG ) Slog .d (TAG , "updating the current intruder:" + notification );
730+ // XXX: this is a hack for Alarms. The real implementation will need to *update*
731+ // the intruder.
732+ if (notification .notification .fullScreenIntent == null ) { // TODO(dsandler): consistent logic with add()
733+ if (DEBUG ) Slog .d (TAG , "no longer intrudes!" );
734+ mHandler .sendEmptyMessage (MSG_HIDE_INTRUDER );
735+ }
736+ }
711737 }
712738
713739 public void removeNotification (IBinder key ) {
714- if (SPEW ) Slog .d (TAG , "removeNotification key=" + key );
715740 StatusBarNotification old = removeNotificationViews (key );
741+ if (SPEW ) Slog .d (TAG , "removeNotification key=" + key + " old=" + old );
716742
717743 if (old != null ) {
718744 // Cancel the ticker if it's still running
719745 mTicker .removeEntry (old );
720746
721747 // Recalculate the position of the sliding windows and the titles.
722748 updateExpandedViewPos (EXPANDED_LEAVE_ALONE );
749+
750+ if (old == mCurrentlyIntrudingNotification ) {
751+ mHandler .sendEmptyMessage (MSG_HIDE_INTRUDER );
752+ }
723753
724754 if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData .size () == 0 && !mAnimating ) {
725755 animateCollapse ();
@@ -1080,6 +1110,7 @@ public void handleMessage(Message m) {
10801110 break ;
10811111 case MSG_HIDE_INTRUDER :
10821112 setIntruderAlertVisibility (false );
1113+ mCurrentlyIntrudingNotification = null ;
10831114 break ;
10841115 case MSG_OPEN_RECENTS_PANEL :
10851116 if (DEBUG ) Slog .d (TAG , "opening recents panel" );
@@ -1576,6 +1607,12 @@ private class NotificationClicker implements View.OnClickListener {
15761607 }
15771608
15781609 public void onClick (View v ) {
1610+ if (DEBUG ) {
1611+ Slog .v (TAG , "NotificationClicker: intent=" + mIntent
1612+ + " pkg=" + mPkg
1613+ + " tag=" + mTag
1614+ + " id=" + mId );
1615+ }
15791616 try {
15801617 // The intent we are sending is for the application, which
15811618 // won't have permission to immediately start an activity after
@@ -2182,9 +2219,25 @@ else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
21822219 };
21832220
21842221 private void setIntruderAlertVisibility (boolean vis ) {
2222+ if (DEBUG ) {
2223+ Slog .v (TAG , (vis ? "showing" : "hiding" ) + " intruder alert window" );
2224+ }
21852225 mIntruderAlertView .setVisibility (vis ? View .VISIBLE : View .GONE );
21862226 }
21872227
2228+ public void dismissIntruder () {
2229+ if (mCurrentlyIntrudingNotification == null ) return ;
2230+
2231+ try {
2232+ mBarService .onNotificationClear (
2233+ mCurrentlyIntrudingNotification .pkg ,
2234+ mCurrentlyIntrudingNotification .tag ,
2235+ mCurrentlyIntrudingNotification .id );
2236+ } catch (android .os .RemoteException ex ) {
2237+ // oh well
2238+ }
2239+ }
2240+
21882241 /**
21892242 * Reload some of our resources when the configuration changes.
21902243 *
0 commit comments