diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index f0db2bce43962..a7cc812e516e6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -34,6 +34,7 @@ import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; +import android.text.TextUtils; import android.util.Log; import android.util.Slog; import android.view.Display; @@ -46,6 +47,7 @@ import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.WindowManager; import android.view.WindowManagerImpl; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RemoteViews; import android.widget.PopupMenu; @@ -61,6 +63,7 @@ import com.android.systemui.recent.RecentsPanelView; import com.android.systemui.recent.RecentTasksLoader; import com.android.systemui.recent.TaskDescription; import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.policy.NotificationRowLayout; import com.android.systemui.statusbar.tablet.StatusBarPanel; import com.android.systemui.R; @@ -76,11 +79,24 @@ public abstract class BaseStatusBar extends SystemUI implements protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023; protected static final int MSG_OPEN_SEARCH_PANEL = 1024; protected static final int MSG_CLOSE_SEARCH_PANEL = 1025; + protected static final int MSG_SHOW_INTRUDER = 1026; + protected static final int MSG_HIDE_INTRUDER = 1027; + + protected static final boolean ENABLE_INTRUDERS = false; + + public static final int EXPANDED_LEAVE_ALONE = -10000; + public static final int EXPANDED_FULL_OPEN = -10001; protected CommandQueue mCommandQueue; protected IStatusBarService mBarService; protected H mHandler = createHandler(); + // all notifications + protected NotificationData mNotificationData = new NotificationData(); + protected NotificationRowLayout mPile; + + protected StatusBarNotification mCurrentlyIntrudingNotification; + // used to notify status bar for suppressing notification LED protected boolean mPanelSlightlyVisible; @@ -633,4 +649,190 @@ public abstract class BaseStatusBar extends SystemUI implements } } + /** + * Cancel this notification and tell the StatusBarManagerService / NotificationManagerService + * about the failure. + * + * WARNING: this will call back into us. Don't hold any locks. + */ + void handleNotificationError(IBinder key, StatusBarNotification n, String message) { + removeNotification(key); + try { + mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message); + } catch (RemoteException ex) { + // The end is nigh. + } + } + + protected StatusBarNotification removeNotificationViews(IBinder key) { + NotificationData.Entry entry = mNotificationData.remove(key); + if (entry == null) { + Slog.w(TAG, "removeNotification for unknown key: " + key); + return null; + } + // Remove the expanded view. + ViewGroup rowParent = (ViewGroup)entry.row.getParent(); + if (rowParent != null) rowParent.removeView(entry.row); + updateNotificationIcons(); + + return entry.notification; + } + + protected StatusBarIconView addNotificationViews(IBinder key, + StatusBarNotification notification) { + if (DEBUG) { + Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification); + } + // Construct the icon. + final StatusBarIconView iconView = new StatusBarIconView(mContext, + notification.pkg + "/0x" + Integer.toHexString(notification.id), + notification.notification); + iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); + + final StatusBarIcon ic = new StatusBarIcon(notification.pkg, + notification.notification.icon, + notification.notification.iconLevel, + notification.notification.number, + notification.notification.tickerText); + if (!iconView.set(ic)) { + handleNotificationError(key, notification, "Couldn't create icon: " + ic); + return null; + } + // Construct the expanded view. + NotificationData.Entry entry = new NotificationData.Entry(key, notification, iconView); + if (!inflateViews(entry, mPile)) { + handleNotificationError(key, notification, "Couldn't expand RemoteViews for: " + + notification); + return null; + } + + // Add the expanded view and icon. + int pos = mNotificationData.add(entry); + if (DEBUG) { + Slog.d(TAG, "addNotificationViews: added at " + pos); + } + updateNotificationIcons(); + + return iconView; + } + + protected abstract void haltTicker(); + protected abstract void setAreThereNotifications(); + protected abstract void updateNotificationIcons(); + protected abstract void tick(IBinder key, StatusBarNotification n, boolean firstTime); + protected abstract void updateExpandedViewPos(int expandedPosition); + + protected boolean isTopNotification(ViewGroup parent, NotificationData.Entry entry) { + return parent.indexOfChild(entry.row) == 0; + } + + public void updateNotification(IBinder key, StatusBarNotification notification) { + if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ")"); + + final NotificationData.Entry oldEntry = mNotificationData.findByKey(key); + if (oldEntry == null) { + Slog.w(TAG, "updateNotification for unknown key: " + key); + return; + } + + final StatusBarNotification oldNotification = oldEntry.notification; + + // XXX: modify when we do something more intelligent with the two content views + final RemoteViews oldContentView = (oldNotification.notification.bigContentView != null) + ? oldNotification.notification.bigContentView + : oldNotification.notification.contentView; + final RemoteViews contentView = (notification.notification.bigContentView != null) + ? notification.notification.bigContentView + : notification.notification.contentView; + + if (DEBUG) { + Slog.d(TAG, "old notification: when=" + oldNotification.notification.when + + " ongoing=" + oldNotification.isOngoing() + + " expanded=" + oldEntry.expanded + + " contentView=" + oldContentView + + " rowParent=" + oldEntry.row.getParent()); + Slog.d(TAG, "new notification: when=" + notification.notification.when + + " ongoing=" + oldNotification.isOngoing() + + " contentView=" + contentView); + } + + // Can we just reapply the RemoteViews in place? If when didn't change, the order + // didn't change. + boolean contentsUnchanged = oldEntry.expanded != null + && contentView != null && oldContentView != null + && contentView.getPackage() != null + && oldContentView.getPackage() != null + && oldContentView.getPackage().equals(contentView.getPackage()) + && oldContentView.getLayoutId() == contentView.getLayoutId(); + ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent(); + boolean orderUnchanged = notification.notification.when==oldNotification.notification.when + && notification.score == oldNotification.score; + // score now encompasses/supersedes isOngoing() + + boolean updateTicker = notification.notification.tickerText != null + && !TextUtils.equals(notification.notification.tickerText, + oldEntry.notification.notification.tickerText); + boolean isTopAnyway = isTopNotification(rowParent, oldEntry); + if (contentsUnchanged && (orderUnchanged || isTopAnyway)) { + if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key); + oldEntry.notification = notification; + try { + // Reapply the RemoteViews + contentView.reapply(mContext, oldEntry.content); + // update the contentIntent + final PendingIntent contentIntent = notification.notification.contentIntent; + if (contentIntent != null) { + final View.OnClickListener listener = makeClicker(contentIntent, + notification.pkg, notification.tag, notification.id); + oldEntry.content.setOnClickListener(listener); + } else { + oldEntry.content.setOnClickListener(null); + } + // Update the icon. + final StatusBarIcon ic = new StatusBarIcon(notification.pkg, + notification.notification.icon, notification.notification.iconLevel, + notification.notification.number, + notification.notification.tickerText); + if (!oldEntry.icon.set(ic)) { + handleNotificationError(key, notification, "Couldn't update icon: " + ic); + return; + } + } + catch (RuntimeException e) { + // It failed to add cleanly. Log, and remove the view from the panel. + Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e); + removeNotificationViews(key); + addNotificationViews(key, notification); + } + } else { + if (DEBUG) Slog.d(TAG, "not reusing notification for key: " + key); + removeNotificationViews(key); + addNotificationViews(key, notification); + } + + // Update the veto button accordingly (and as a result, whether this row is + // swipe-dismissable) + updateNotificationVetoButton(oldEntry.row, notification); + + // Restart the ticker if it's still running + if (updateTicker) { + haltTicker(); + tick(key, notification, false); + } + + // Recalculate the position of the sliding windows and the titles. + setAreThereNotifications(); + updateExpandedViewPos(EXPANDED_LEAVE_ALONE); + + // See if we need to update the intruder. + if (ENABLE_INTRUDERS && oldNotification == mCurrentlyIntrudingNotification) { + if (DEBUG) Slog.d(TAG, "updating the current intruder:" + notification); + // XXX: this is a hack for Alarms. The real implementation will need to *update* + // the intruder. + if (notification.notification.fullScreenIntent == null) { // TODO(dsandler): consistent logic with add() + if (DEBUG) Slog.d(TAG, "no longer intrudes!"); + mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER); + } + } + } } 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 f53a2823e936c..320dd6ad2c21f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -42,7 +42,6 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.provider.Settings; -import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; import android.util.Slog; @@ -105,16 +104,10 @@ public class PhoneStatusBar extends BaseStatusBar { public static final String ACTION_STATUSBAR_START = "com.android.internal.policy.statusbar.START"; - private static final boolean ENABLE_INTRUDERS = false; private static final boolean DIM_BEHIND_EXPANDED_PANEL = false; - static final int EXPANDED_LEAVE_ALONE = -10000; - static final int EXPANDED_FULL_OPEN = -10001; - private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000; private static final int MSG_CLOSE_NOTIFICATION_PANEL = 1001; - private static final int MSG_SHOW_INTRUDER = 1002; - private static final int MSG_HIDE_INTRUDER = 1003; // 1020-1030 reserved for BaseStatusBar // will likely move to a resource or other tunable param at some point @@ -179,10 +172,6 @@ public class PhoneStatusBar extends BaseStatusBar { CloseDragHandle mCloseView; private int mCloseViewHeight; - // all notifications - NotificationData mNotificationData = new NotificationData(); - NotificationRowLayout mPile; - // position int[] mPositionTmp = new int[2]; boolean mExpanded; @@ -518,7 +507,7 @@ public class PhoneStatusBar extends BaseStatusBar { toggleRecentApps(); } }; - private StatusBarNotification mCurrentlyIntrudingNotification; + View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { switch(event.getAction()) { @@ -693,7 +682,7 @@ public class PhoneStatusBar extends BaseStatusBar { // show the ticker if there isn't an intruder too if (mCurrentlyIntrudingNotification == null) { - tick(notification); + tick(null, notification, true); } } @@ -702,117 +691,6 @@ public class PhoneStatusBar extends BaseStatusBar { updateExpandedViewPos(EXPANDED_LEAVE_ALONE); } - public void updateNotification(IBinder key, StatusBarNotification notification) { - if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ")"); - - final NotificationData.Entry oldEntry = mNotificationData.findByKey(key); - if (oldEntry == null) { - Slog.w(TAG, "updateNotification for unknown key: " + key); - return; - } - - final StatusBarNotification oldNotification = oldEntry.notification; - - // XXX: modify when we do something more intelligent with the two content views - final RemoteViews oldContentView = (oldNotification.notification.bigContentView != null) - ? oldNotification.notification.bigContentView - : oldNotification.notification.contentView; - final RemoteViews contentView = (notification.notification.bigContentView != null) - ? notification.notification.bigContentView - : notification.notification.contentView; - - if (DEBUG) { - Slog.d(TAG, "old notification: when=" + oldNotification.notification.when - + " ongoing=" + oldNotification.isOngoing() - + " expanded=" + oldEntry.expanded - + " contentView=" + oldContentView - + " rowParent=" + oldEntry.row.getParent()); - Slog.d(TAG, "new notification: when=" + notification.notification.when - + " ongoing=" + oldNotification.isOngoing() - + " contentView=" + contentView); - } - - - // Can we just reapply the RemoteViews in place? If when didn't change, the order - // didn't change. - boolean contentsUnchanged = oldEntry.expanded != null - && contentView != null && oldContentView != null - && contentView.getPackage() != null - && oldContentView.getPackage() != null - && oldContentView.getPackage().equals(contentView.getPackage()) - && oldContentView.getLayoutId() == contentView.getLayoutId(); - ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent(); - boolean orderUnchanged = notification.notification.when==oldNotification.notification.when - && notification.score == oldNotification.score; - // score now encompasses/supersedes isOngoing() - - boolean updateTicker = notification.notification.tickerText != null - && !TextUtils.equals(notification.notification.tickerText, - oldEntry.notification.notification.tickerText); - boolean isFirstAnyway = rowParent.indexOfChild(oldEntry.row) == 0; - if (contentsUnchanged && (orderUnchanged || isFirstAnyway)) { - if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key); - oldEntry.notification = notification; - try { - // Reapply the RemoteViews - contentView.reapply(mContext, oldEntry.content); - // update the contentIntent - final PendingIntent contentIntent = notification.notification.contentIntent; - if (contentIntent != null) { - final View.OnClickListener listener = new NotificationClicker(contentIntent, - notification.pkg, notification.tag, notification.id); - oldEntry.content.setOnClickListener(listener); - } else { - oldEntry.content.setOnClickListener(null); - } - // Update the icon. - final StatusBarIcon ic = new StatusBarIcon(notification.pkg, - notification.notification.icon, notification.notification.iconLevel, - notification.notification.number, - notification.notification.tickerText); - if (!oldEntry.icon.set(ic)) { - handleNotificationError(key, notification, "Couldn't update icon: " + ic); - return; - } - } - catch (RuntimeException e) { - // It failed to add cleanly. Log, and remove the view from the panel. - Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e); - removeNotificationViews(key); - addNotificationViews(key, notification); - } - } else { - if (SPEW) Slog.d(TAG, "not reusing notification"); - removeNotificationViews(key); - addNotificationViews(key, notification); - } - - // Update the veto button accordingly (and as a result, whether this row is - // swipe-dismissable) - updateNotificationVetoButton(oldEntry.row, notification); - - // Restart the ticker if it's still running - if (updateTicker) { - mTicker.halt(); - tick(notification); - } - - // Recalculate the position of the sliding windows and the titles. - setAreThereNotifications(); - updateExpandedViewPos(EXPANDED_LEAVE_ALONE); - - // See if we need to update the intruder. - if (ENABLE_INTRUDERS && oldNotification == mCurrentlyIntrudingNotification) { - if (DEBUG) Slog.d(TAG, "updating the current intruder:" + notification); - // XXX: this is a hack for Alarms. The real implementation will need to *update* - // the intruder. - if (notification.notification.fullScreenIntent == null) { // TODO(dsandler): consistent logic with add() - if (DEBUG) Slog.d(TAG, "no longer intrudes!"); - mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER); - } - } - } - public void removeNotification(IBinder key) { StatusBarNotification old = removeNotificationViews(key); if (SPEW) Slog.d(TAG, "removeNotification key=" + key + " old=" + old); @@ -841,44 +719,6 @@ public class PhoneStatusBar extends BaseStatusBar { updateRecentsPanel(); } - - StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) { - if (DEBUG) { - Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification); - } - // Construct the icon. - final StatusBarIconView iconView = new StatusBarIconView(mContext, - notification.pkg + "/0x" + Integer.toHexString(notification.id), - notification.notification); - iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); - - final StatusBarIcon ic = new StatusBarIcon(notification.pkg, - notification.notification.icon, - notification.notification.iconLevel, - notification.notification.number, - notification.notification.tickerText); - if (!iconView.set(ic)) { - handleNotificationError(key, notification, "Couldn't create icon: " + ic); - return null; - } - // Construct the expanded view. - NotificationData.Entry entry = new NotificationData.Entry(key, notification, iconView); - if (!inflateViews(entry, mPile)) { - handleNotificationError(key, notification, "Couldn't expand RemoteViews for: " - + notification); - return null; - } - - // Add the expanded view and icon. - int pos = mNotificationData.add(entry); - if (DEBUG) { - Slog.d(TAG, "addNotificationViews: added at " + pos); - } - updateNotificationIcons(); - - return iconView; - } - private void loadNotificationShade() { int N = mNotificationData.size(); @@ -915,7 +755,8 @@ public class PhoneStatusBar extends BaseStatusBar { updateNotificationIcons(); } - private void updateNotificationIcons() { + @Override + protected void updateNotificationIcons() { loadNotificationShade(); final LinearLayout.LayoutParams params @@ -956,21 +797,8 @@ public class PhoneStatusBar extends BaseStatusBar { } } - StatusBarNotification removeNotificationViews(IBinder key) { - NotificationData.Entry entry = mNotificationData.remove(key); - if (entry == null) { - Slog.w(TAG, "removeNotification for unknown key: " + key); - return null; - } - // Remove the expanded view. - ViewGroup rowParent = (ViewGroup)entry.row.getParent(); - if (rowParent != null) rowParent.removeView(entry.row); - updateNotificationIcons(); - - return entry.notification; - } - - private void setAreThereNotifications() { + @Override + protected void setAreThereNotifications() { final boolean any = mNotificationData.size() > 0; final boolean clearable = any && mNotificationData.hasClearableItems(); @@ -1754,7 +1582,8 @@ public class PhoneStatusBar extends BaseStatusBar { } } - private void tick(StatusBarNotification n) { + @Override + protected void tick(IBinder key, StatusBarNotification n, boolean firstTime) { // no ticking in lights-out mode if (!areLightsOn()) return; @@ -1770,21 +1599,6 @@ public class PhoneStatusBar extends BaseStatusBar { } } - /** - * Cancel this notification and tell the StatusBarManagerService / NotificationManagerService - * about the failure. - * - * WARNING: this will call back into us. Don't hold any locks. - */ - void handleNotificationError(IBinder key, StatusBarNotification n, String message) { - removeNotification(key); - try { - mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message); - } catch (RemoteException ex) { - // The end is nigh. - } - } - private class MyTicker extends Ticker { MyTicker(Context context, View sb) { super(context, sb); @@ -1961,7 +1775,8 @@ public class PhoneStatusBar extends BaseStatusBar { return mDisplayMetrics.heightPixels - mNotificationPanelMarginBottomPx; } - void updateExpandedViewPos(int expandedPosition) { + @Override + protected void updateExpandedViewPos(int expandedPosition) { if (SPEW) { Slog.d(TAG, "updateExpandedViewPos before expandedPosition=" + expandedPosition //+ " mTrackingParams.y=" + ((mTrackingParams == null) ? "?" : mTrackingParams.y) @@ -2288,5 +2103,10 @@ public class PhoneStatusBar extends BaseStatusBar { vibrate(); } }; + + @Override + protected void haltTicker() { + mTicker.halt(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index a8f5c6463c218..a9cc62a4d6157 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -31,6 +31,7 @@ import android.view.accessibility.AccessibilityEvent; import android.widget.FrameLayout; import com.android.systemui.R; +import com.android.systemui.statusbar.BaseStatusBar; import com.android.systemui.statusbar.policy.FixedSizeDrawable; public class PhoneStatusBarView extends FrameLayout { @@ -95,7 +96,7 @@ public class PhoneStatusBarView extends FrameLayout { @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); - mService.updateExpandedViewPos(PhoneStatusBar.EXPANDED_LEAVE_ALONE); + mService.updateExpandedViewPos(BaseStatusBar.EXPANDED_LEAVE_ALONE); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index a39459659489e..6a7d6b098601d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -109,7 +109,6 @@ public class TabletStatusBar extends BaseStatusBar implements private static final boolean FAKE_SPACE_BAR = true; // Notification "peeking" (flyover preview of individual notifications) - final static boolean NOTIFICATION_PEEK_ENABLED = false; final static int NOTIFICATION_PEEK_HOLD_THRESH = 200; // ms final static int NOTIFICATION_PEEK_FADE_DELAY = 3000; // ms @@ -127,9 +126,6 @@ public class TabletStatusBar extends BaseStatusBar implements IWindowManager mWindowManager; - // tracking all current notifications - private NotificationData mNotificationData = new NotificationData(); - TabletStatusBarView mStatusBarView; View mNotificationArea; View mNotificationTrigger; @@ -160,8 +156,6 @@ public class TabletStatusBar extends BaseStatusBar implements int mNotificationPeekTapDuration; int mNotificationFlingVelocity; - NotificationRowLayout mPile; - BatteryController mBatteryController; BluetoothController mBluetoothController; LocationController mLocationController; @@ -290,47 +284,6 @@ public class TabletStatusBar extends BaseStatusBar implements WindowManagerImpl.getDefault().addView(mNotificationPanel, lp); - // Notification preview window - if (NOTIFICATION_PEEK_ENABLED) { - mNotificationPeekWindow = (NotificationPeekPanel) View.inflate(context, - R.layout.system_bar_notification_peek, null); - mNotificationPeekWindow.setBar(this); - - mNotificationPeekRow = (ViewGroup) mNotificationPeekWindow.findViewById(R.id.content); - mNotificationPeekWindow.setVisibility(View.GONE); - mNotificationPeekWindow.setOnTouchListener( - new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PEEK, mNotificationPeekWindow)); - mNotificationPeekScrubRight = new LayoutTransition(); - mNotificationPeekScrubRight.setAnimator(LayoutTransition.APPEARING, - ObjectAnimator.ofInt(null, "left", -512, 0)); - mNotificationPeekScrubRight.setAnimator(LayoutTransition.DISAPPEARING, - ObjectAnimator.ofInt(null, "left", -512, 0)); - mNotificationPeekScrubRight.setDuration(500); - - mNotificationPeekScrubLeft = new LayoutTransition(); - mNotificationPeekScrubLeft.setAnimator(LayoutTransition.APPEARING, - ObjectAnimator.ofInt(null, "left", 512, 0)); - mNotificationPeekScrubLeft.setAnimator(LayoutTransition.DISAPPEARING, - ObjectAnimator.ofInt(null, "left", 512, 0)); - mNotificationPeekScrubLeft.setDuration(500); - - // XXX: setIgnoreChildren? - lp = new WindowManager.LayoutParams( - 512, // ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT, - WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, - WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS - | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM - | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, - PixelFormat.TRANSLUCENT); - lp.gravity = Gravity.BOTTOM | Gravity.RIGHT; - lp.y = res.getDimensionPixelOffset(R.dimen.peek_window_y_offset); - lp.setTitle("NotificationPeekWindow"); - lp.windowAnimations = com.android.internal.R.style.Animation_Toast; - - WindowManagerImpl.getDefault().addView(mNotificationPeekWindow, lp); - } - // Recents Panel mRecentTasksLoader = new RecentTasksLoader(context); updateRecentsPanel(); @@ -494,24 +447,16 @@ public class TabletStatusBar extends BaseStatusBar implements // the whole right-hand side of the bar mNotificationArea = sb.findViewById(R.id.notificationArea); - if (!NOTIFICATION_PEEK_ENABLED) { - mNotificationArea.setOnTouchListener(new NotificationTriggerTouchListener()); - } + mNotificationArea.setOnTouchListener(new NotificationTriggerTouchListener()); // the button to open the notification area mNotificationTrigger = sb.findViewById(R.id.notificationTrigger); - if (NOTIFICATION_PEEK_ENABLED) { - mNotificationTrigger.setOnTouchListener(new NotificationTriggerTouchListener()); - } // the more notifications icon mNotificationIconArea = (NotificationIconArea)sb.findViewById(R.id.notificationIcons); // where the icons go mIconLayout = (NotificationIconArea.IconLayout) sb.findViewById(R.id.icons); - if (NOTIFICATION_PEEK_ENABLED) { - mIconLayout.setOnTouchListener(new NotificationIconTouchListener()); - } ViewConfiguration vc = ViewConfiguration.get(context); mNotificationPeekTapDuration = vc.getTapTimeout(); @@ -829,9 +774,6 @@ public class TabletStatusBar extends BaseStatusBar implements case MSG_OPEN_NOTIFICATION_PANEL: if (DEBUG) Slog.d(TAG, "opening notifications panel"); if (!mNotificationPanel.isShowing()) { - if (NOTIFICATION_PEEK_ENABLED) { - mNotificationPeekWindow.setVisibility(View.GONE); - } mNotificationPanel.show(true, true); mNotificationArea.setVisibility(View.INVISIBLE); mTicker.halt(); @@ -918,106 +860,6 @@ public class TabletStatusBar extends BaseStatusBar implements setAreThereNotifications(); } - public void updateNotification(IBinder key, StatusBarNotification notification) { - if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ")"); - - final NotificationData.Entry oldEntry = mNotificationData.findByKey(key); - if (oldEntry == null) { - Slog.w(TAG, "updateNotification for unknown key: " + key); - return; - } - - final StatusBarNotification oldNotification = oldEntry.notification; - - // XXX: modify when we do something more intelligent with the two content views - final RemoteViews oldContentView = (oldNotification.notification.bigContentView != null) - ? oldNotification.notification.bigContentView - : oldNotification.notification.contentView; - final RemoteViews contentView = (notification.notification.bigContentView != null) - ? notification.notification.bigContentView - : notification.notification.contentView; - - if (DEBUG) { - Slog.d(TAG, "old notification: when=" + oldNotification.notification.when - + " ongoing=" + oldNotification.isOngoing() - + " expanded=" + oldEntry.expanded - + " contentView=" + oldContentView - + " rowParent=" + oldEntry.row.getParent()); - Slog.d(TAG, "new notification: when=" + notification.notification.when - + " ongoing=" + oldNotification.isOngoing() - + " contentView=" + contentView); - } - - // Can we just reapply the RemoteViews in place? If when didn't change, the order - // didn't change. - boolean contentsUnchanged = oldEntry.expanded != null - && contentView != null && oldContentView != null - && contentView.getPackage() != null - && oldContentView.getPackage() != null - && oldContentView.getPackage().equals(contentView.getPackage()) - && oldContentView.getLayoutId() == contentView.getLayoutId(); - ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent(); - boolean orderUnchanged = notification.notification.when==oldNotification.notification.when - && notification.score == oldNotification.score; - // score now encompasses/supersedes isOngoing() - boolean updateTicker = notification.notification.tickerText != null - && !TextUtils.equals(notification.notification.tickerText, - oldEntry.notification.notification.tickerText); - boolean isLastAnyway = rowParent.indexOfChild(oldEntry.row) == rowParent.getChildCount()-1; - if (contentsUnchanged && (orderUnchanged || isLastAnyway)) { - if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key); - oldEntry.notification = notification; - try { - // Reapply the RemoteViews - contentView.reapply(mContext, oldEntry.content); - // update the contentIntent - final PendingIntent contentIntent = notification.notification.contentIntent; - if (contentIntent != null) { - final View.OnClickListener listener = makeClicker(contentIntent, - notification.pkg, notification.tag, notification.id); - oldEntry.content.setOnClickListener(listener); - } else { - oldEntry.content.setOnClickListener(null); - } - // Update the icon. - final StatusBarIcon ic = new StatusBarIcon(notification.pkg, - notification.notification.icon, notification.notification.iconLevel, - notification.notification.number, - notification.notification.tickerText); - if (!oldEntry.icon.set(ic)) { - handleNotificationError(key, notification, "Couldn't update icon: " + ic); - return; - } - - if (NOTIFICATION_PEEK_ENABLED && key == mNotificationPeekKey) { - // must update the peek window - Message peekMsg = mHandler.obtainMessage(MSG_OPEN_NOTIFICATION_PEEK); - peekMsg.arg1 = mNotificationPeekIndex; - mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK); - mHandler.sendMessage(peekMsg); - } - } - catch (RuntimeException e) { - // It failed to add cleanly. Log, and remove the view from the panel. - Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e); - removeNotificationViews(key); - addNotificationViews(key, notification); - } - } else { - if (DEBUG) Slog.d(TAG, "not reusing notification for key: " + key); - removeNotificationViews(key); - addNotificationViews(key, notification); - } - - // Restart the ticker if it's still running - if (updateTicker) { - mTicker.halt(); - tick(key, notification, false); - } - - setAreThereNotifications(); - } - public void removeNotification(IBinder key) { if (DEBUG) Slog.d(TAG, "removeNotification(" + key + ")"); removeNotificationViews(key); @@ -1107,7 +949,8 @@ public class TabletStatusBar extends BaseStatusBar implements return n.tickerView != null || !TextUtils.isEmpty(n.tickerText); } - private void tick(IBinder key, StatusBarNotification n, boolean firstTime) { + @Override + protected void tick(IBinder key, StatusBarNotification n, boolean firstTime) { // Don't show the ticker when the windowshade is open. if (mNotificationPanel.isShowing()) { return; @@ -1136,11 +979,6 @@ public class TabletStatusBar extends BaseStatusBar implements } public void animateExpand() { - if (NOTIFICATION_PEEK_ENABLED) { - mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PEEK); - mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK); - mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK); - } mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PANEL); mHandler.sendEmptyMessage(MSG_OPEN_NOTIFICATION_PANEL); } @@ -1160,10 +998,6 @@ public class TabletStatusBar extends BaseStatusBar implements mHandler.sendEmptyMessage(MSG_CLOSE_INPUT_METHODS_PANEL); mHandler.removeMessages(MSG_CLOSE_COMPAT_MODE_PANEL); mHandler.sendEmptyMessage(MSG_CLOSE_COMPAT_MODE_PANEL); - if (NOTIFICATION_PEEK_ENABLED) { - mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PEEK); - mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK); - } } @Override // CommandQueue @@ -1352,24 +1186,13 @@ public class TabletStatusBar extends BaseStatusBar implements } } - private void setAreThereNotifications() { + @Override + protected void setAreThereNotifications() { if (mNotificationPanel != null) { mNotificationPanel.setClearable(mNotificationData.hasClearableItems()); } } - /** - * Cancel this notification and tell the status bar service about the failure. Hold no locks. - */ - void handleNotificationError(IBinder key, StatusBarNotification n, String message) { - removeNotification(key); - try { - mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message); - } catch (RemoteException ex) { - // The end is nigh. - } - } - private View.OnClickListener mOnClickListener = new View.OnClickListener() { public void onClick(View v) { if (v == mRecentButton) { @@ -1407,28 +1230,6 @@ public class TabletStatusBar extends BaseStatusBar implements mHandler.sendEmptyMessage(msg); } - StatusBarNotification removeNotificationViews(IBinder key) { - NotificationData.Entry entry = mNotificationData.remove(key); - if (entry == null) { - Slog.w(TAG, "removeNotification for unknown key: " + key); - return null; - } - // Remove the expanded view. - ViewGroup rowParent = (ViewGroup)entry.row.getParent(); - if (rowParent != null) rowParent.removeView(entry.row); - - if (NOTIFICATION_PEEK_ENABLED && key == mNotificationPeekKey) { - // must close the peek as well, since it's gone - mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK); - } - // Remove the icon. -// ViewGroup iconParent = (ViewGroup)entry.icon.getParent(); -// if (iconParent != null) iconParent.removeView(entry.icon); - updateNotificationIcons(); - - return entry.notification; - } - private class NotificationTriggerTouchListener implements View.OnTouchListener { VelocityTracker mVT; float mInitialTouchX, mInitialTouchY; @@ -1621,50 +1422,14 @@ public class TabletStatusBar extends BaseStatusBar implements } } - StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) { - if (DEBUG) { - Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification); - } - // Construct the icon. - final StatusBarIconView iconView = new StatusBarIconView(mContext, - notification.pkg + "/0x" + Integer.toHexString(notification.id), - notification.notification); - iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); - - final StatusBarIcon ic = new StatusBarIcon(notification.pkg, - notification.notification.icon, - notification.notification.iconLevel, - notification.notification.number, - notification.notification.tickerText); - if (!iconView.set(ic)) { - handleNotificationError(key, notification, "Couldn't attach StatusBarIcon: " + ic); - return null; - } - // Construct the expanded view. - NotificationData.Entry entry = new NotificationData.Entry(key, notification, iconView); - if (!inflateViews(entry, mPile)) { - handleNotificationError(key, notification, "Couldn't expand RemoteViews for: " - + notification); - return null; - } - - // Add the icon. - int pos = mNotificationData.add(entry); - if (DEBUG) { - Slog.d(TAG, "addNotificationViews: added at " + pos); - } - updateNotificationIcons(); - - return iconView; - } - private void reloadAllNotificationIcons() { if (mIconLayout == null) return; mIconLayout.removeAllViews(); updateNotificationIcons(); } - private void updateNotificationIcons() { + @Override + protected void updateNotificationIcons() { // XXX: need to implement a new limited linear layout class // to avoid removing & readding everything @@ -1837,6 +1602,19 @@ public class TabletStatusBar extends BaseStatusBar implements mNetworkController.dump(fd, pw, args); } + @Override + protected boolean isTopNotification(ViewGroup parent, NotificationData.Entry entry) { + return parent.indexOfChild(entry.row) == parent.getChildCount()-1; + } + + @Override + protected void haltTicker() { + mTicker.halt(); + } + + @Override + protected void updateExpandedViewPos(int expandedPosition) { + } }