Loading packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java +27 −11 Original line number Original line Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.systemui.statusbar; package com.android.systemui.statusbar; import com.android.internal.util.CharSequences; import com.android.internal.statusbar.IStatusBar; import com.android.internal.statusbar.IStatusBar; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.statusbar.StatusBarIcon; Loading Loading @@ -334,7 +333,7 @@ public class PhoneStatusBarService extends StatusBarService { addNotificationViews(key, notification); addNotificationViews(key, notification); // show the ticker // show the ticker // TODO tick(notification); // Recalculate the position of the sliding windows and the titles. // Recalculate the position of the sliding windows and the titles. setAreThereNotifications(); setAreThereNotifications(); Loading Loading @@ -400,7 +399,7 @@ public class PhoneStatusBarService extends StatusBarService { } } // Restart the ticker if it's still running // Restart the ticker if it's still running // TODO tick(notification); // Recalculate the position of the sliding windows and the titles. // Recalculate the position of the sliding windows and the titles. setAreThereNotifications(); setAreThereNotifications(); Loading @@ -409,15 +408,17 @@ public class PhoneStatusBarService extends StatusBarService { public void removeNotification(IBinder key) { public void removeNotification(IBinder key) { Slog.d(TAG, "removeNotification key=" + key); Slog.d(TAG, "removeNotification key=" + key); removeNotificationViews(key); StatusBarNotification old = removeNotificationViews(key); if (old != null) { // Cancel the ticker if it's still running // Cancel the ticker if it's still running // TODO mTicker.removeEntry(old); // Recalculate the position of the sliding windows and the titles. // Recalculate the position of the sliding windows and the titles. setAreThereNotifications(); setAreThereNotifications(); updateExpandedViewPos(EXPANDED_LEAVE_ALONE); updateExpandedViewPos(EXPANDED_LEAVE_ALONE); } } } private int chooseIconIndex(boolean isOngoing, int viewIndex) { private int chooseIconIndex(boolean isOngoing, int viewIndex) { final int latestSize = mLatest.size(); final int latestSize = mLatest.size(); Loading Loading @@ -499,19 +500,21 @@ public class PhoneStatusBarService extends StatusBarService { new LinearLayout.LayoutParams(mIconWidth, mHeight)); new LinearLayout.LayoutParams(mIconWidth, mHeight)); } } void removeNotificationViews(IBinder key) { StatusBarNotification removeNotificationViews(IBinder key) { NotificationData.Entry entry = mOngoing.remove(key); NotificationData.Entry entry = mOngoing.remove(key); if (entry == null) { if (entry == null) { entry = mLatest.remove(key); entry = mLatest.remove(key); if (entry == null) { if (entry == null) { Slog.w(TAG, "removeNotification for unknown key: " + key); Slog.w(TAG, "removeNotification for unknown key: " + key); return; return null; } } } } // Remove the expanded view. // Remove the expanded view. ((ViewGroup)entry.row.getParent()).removeView(entry.row); ((ViewGroup)entry.row.getParent()).removeView(entry.row); // Remove the icon. // Remove the icon. ((ViewGroup)entry.icon.getParent()).removeView(entry.icon); ((ViewGroup)entry.icon.getParent()).removeView(entry.icon); return entry.notification; } } private void setAreThereNotifications() { private void setAreThereNotifications() { Loading Loading @@ -960,6 +963,19 @@ public class PhoneStatusBarService extends StatusBarService { } } } } private void tick(StatusBarNotification n) { // Show the ticker if one is requested. Also don't do this // until status bar window is attached to the window manager, // because... well, what's the point otherwise? And trying to // run a ticker without being attached will crash! if (n.notification.tickerText != null && mStatusBarView.getWindowToken() != null) { if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) { mTicker.addEntry(n); } } } private class MyTicker extends Ticker { private class MyTicker extends Ticker { MyTicker(Context context, StatusBarView sb) { MyTicker(Context context, StatusBarView sb) { super(context, sb); super(context, sb); Loading packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +6 −3 Original line number Original line Diff line number Diff line Loading @@ -69,6 +69,7 @@ public class StatusBarIconView extends AnimatedImageView { Drawable drawable = getIcon(icon); Drawable drawable = getIcon(icon); if (drawable == null) { if (drawable == null) { mError = true; mError = true; Slog.w(PhoneStatusBarService.TAG, "No icon ID for slot " + mSlot); break error; break error; } } setImageDrawable(drawable); setImageDrawable(drawable); Loading @@ -86,6 +87,10 @@ public class StatusBarIconView extends AnimatedImageView { } } } } private Drawable getIcon(StatusBarIcon icon) { return getIcon(getContext(), icon); } /** /** * Returns the right icon to use for this item, respecting the iconId and * Returns the right icon to use for this item, respecting the iconId and * iconPackage (if set) * iconPackage (if set) Loading @@ -94,8 +99,7 @@ public class StatusBarIconView extends AnimatedImageView { * @return Drawable for this item, or null if the package or item could not * @return Drawable for this item, or null if the package or item could not * be found * be found */ */ private Drawable getIcon(StatusBarIcon icon) { public static Drawable getIcon(Context context, StatusBarIcon icon) { Context context = getContext(); Resources r = null; Resources r = null; if (icon.iconPackage != null) { if (icon.iconPackage != null) { Loading @@ -110,7 +114,6 @@ public class StatusBarIconView extends AnimatedImageView { } } if (icon.iconId == 0) { if (icon.iconId == 0) { Slog.w(PhoneStatusBarService.TAG, "No icon ID for slot " + mSlot); return null; return null; } } Loading packages/SystemUI/src/com/android/systemui/statusbar/Ticker.java +45 −18 Original line number Original line Diff line number Diff line Loading @@ -33,14 +33,24 @@ import android.widget.ImageSwitcher; import java.util.ArrayList; import java.util.ArrayList; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.statusbar.StatusBarNotification; import com.android.internal.statusbar.StatusBarNotification; import com.android.internal.util.CharSequences; import com.android.systemui.R; import com.android.systemui.R; public abstract class Ticker { public abstract class Ticker { private static final int TICKER_SEGMENT_DELAY = 3000; private static final int TICKER_SEGMENT_DELAY = 3000; private Context mContext; private Handler mHandler = new Handler(); private ArrayList<Segment> mSegments = new ArrayList(); private TextPaint mPaint; private View mTickerView; private ImageSwitcher mIconSwitcher; private TextSwitcher mTextSwitcher; private final class Segment { private final class Segment { StatusBarNotification notificationData; StatusBarNotification notification; Drawable icon; Drawable icon; CharSequence text; CharSequence text; int current; int current; Loading Loading @@ -117,7 +127,7 @@ public abstract class Ticker { } } Segment(StatusBarNotification n, Drawable icon, CharSequence text) { Segment(StatusBarNotification n, Drawable icon, CharSequence text) { this.notificationData = n; this.notification = n; this.icon = icon; this.icon = icon; this.text = text; this.text = text; int index = 0; int index = 0; Loading @@ -131,14 +141,8 @@ public abstract class Ticker { } } }; }; private Handler mHandler = new Handler(); private ArrayList<Segment> mSegments = new ArrayList(); private TextPaint mPaint; private View mTickerView; private ImageSwitcher mIconSwitcher; private TextSwitcher mTextSwitcher; Ticker(Context context, StatusBarView sb) { Ticker(Context context, StatusBarView sb) { mContext = context; mTickerView = sb.findViewById(R.id.ticker); mTickerView = sb.findViewById(R.id.ticker); mIconSwitcher = (ImageSwitcher)sb.findViewById(R.id.tickerIcon); mIconSwitcher = (ImageSwitcher)sb.findViewById(R.id.tickerIcon); Loading @@ -158,20 +162,34 @@ public abstract class Ticker { mPaint = text.getPaint(); mPaint = text.getPaint(); } } void addEntry(StatusBarNotification n, Drawable icon, CharSequence text) { void addEntry(StatusBarNotification n) { int initialCount = mSegments.size(); int initialCount = mSegments.size(); Segment newSegment = new Segment(n, icon, text); // If what's being displayed has the same text and icon, just drop it // (which will let the current one finish, this happens when apps do // a notification storm). if (initialCount > 0) { final Segment seg = mSegments.get(0); if (n.pkg.equals(seg.notification.pkg) && n.notification.icon == seg.notification.notification.icon && n.notification.iconLevel == seg.notification.notification.iconLevel && CharSequences.equals(seg.notification.notification.tickerText, n.notification.tickerText)) { return; } } final Drawable icon = StatusBarIconView.getIcon(mContext, new StatusBarIcon(n.pkg, n.notification.icon, n.notification.iconLevel, 0)); final Segment newSegment = new Segment(n, icon, n.notification.tickerText); // prune out any preexisting ones for this notification, but not the current one. // If there's already a notification schedule for this package and id, remove it. // let that finish, even if it's the same id for (int i=0; i<initialCount; i++) { for (int i=1; i<initialCount; i++) { Segment seg = mSegments.get(i); Segment seg = mSegments.get(i); if (n.id == seg.notificationData.id && n.pkg.equals(seg.notificationData.pkg)) { if (n.id == seg.notification.id && n.pkg.equals(seg.notification.pkg)) { // just update that one to use this new data instead // just update that one to use this new data instead mSegments.set(i, newSegment); mSegments.remove(i); // and since we know initialCount != 0, just return return ; } } } } Loading @@ -194,6 +212,15 @@ public abstract class Ticker { } } } } void removeEntry(StatusBarNotification n) { for (int i=mSegments.size()-1; i>=0; i--) { Segment seg = mSegments.get(i); if (n.id == seg.notification.id && n.pkg.equals(seg.notification.pkg)) { mSegments.remove(i); } } } void halt() { void halt() { mHandler.removeCallbacks(mAdvanceTicker); mHandler.removeCallbacks(mAdvanceTicker); mSegments.clear(); mSegments.clear(); Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java +27 −11 Original line number Original line Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.systemui.statusbar; package com.android.systemui.statusbar; import com.android.internal.util.CharSequences; import com.android.internal.statusbar.IStatusBar; import com.android.internal.statusbar.IStatusBar; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.statusbar.StatusBarIcon; Loading Loading @@ -334,7 +333,7 @@ public class PhoneStatusBarService extends StatusBarService { addNotificationViews(key, notification); addNotificationViews(key, notification); // show the ticker // show the ticker // TODO tick(notification); // Recalculate the position of the sliding windows and the titles. // Recalculate the position of the sliding windows and the titles. setAreThereNotifications(); setAreThereNotifications(); Loading Loading @@ -400,7 +399,7 @@ public class PhoneStatusBarService extends StatusBarService { } } // Restart the ticker if it's still running // Restart the ticker if it's still running // TODO tick(notification); // Recalculate the position of the sliding windows and the titles. // Recalculate the position of the sliding windows and the titles. setAreThereNotifications(); setAreThereNotifications(); Loading @@ -409,15 +408,17 @@ public class PhoneStatusBarService extends StatusBarService { public void removeNotification(IBinder key) { public void removeNotification(IBinder key) { Slog.d(TAG, "removeNotification key=" + key); Slog.d(TAG, "removeNotification key=" + key); removeNotificationViews(key); StatusBarNotification old = removeNotificationViews(key); if (old != null) { // Cancel the ticker if it's still running // Cancel the ticker if it's still running // TODO mTicker.removeEntry(old); // Recalculate the position of the sliding windows and the titles. // Recalculate the position of the sliding windows and the titles. setAreThereNotifications(); setAreThereNotifications(); updateExpandedViewPos(EXPANDED_LEAVE_ALONE); updateExpandedViewPos(EXPANDED_LEAVE_ALONE); } } } private int chooseIconIndex(boolean isOngoing, int viewIndex) { private int chooseIconIndex(boolean isOngoing, int viewIndex) { final int latestSize = mLatest.size(); final int latestSize = mLatest.size(); Loading Loading @@ -499,19 +500,21 @@ public class PhoneStatusBarService extends StatusBarService { new LinearLayout.LayoutParams(mIconWidth, mHeight)); new LinearLayout.LayoutParams(mIconWidth, mHeight)); } } void removeNotificationViews(IBinder key) { StatusBarNotification removeNotificationViews(IBinder key) { NotificationData.Entry entry = mOngoing.remove(key); NotificationData.Entry entry = mOngoing.remove(key); if (entry == null) { if (entry == null) { entry = mLatest.remove(key); entry = mLatest.remove(key); if (entry == null) { if (entry == null) { Slog.w(TAG, "removeNotification for unknown key: " + key); Slog.w(TAG, "removeNotification for unknown key: " + key); return; return null; } } } } // Remove the expanded view. // Remove the expanded view. ((ViewGroup)entry.row.getParent()).removeView(entry.row); ((ViewGroup)entry.row.getParent()).removeView(entry.row); // Remove the icon. // Remove the icon. ((ViewGroup)entry.icon.getParent()).removeView(entry.icon); ((ViewGroup)entry.icon.getParent()).removeView(entry.icon); return entry.notification; } } private void setAreThereNotifications() { private void setAreThereNotifications() { Loading Loading @@ -960,6 +963,19 @@ public class PhoneStatusBarService extends StatusBarService { } } } } private void tick(StatusBarNotification n) { // Show the ticker if one is requested. Also don't do this // until status bar window is attached to the window manager, // because... well, what's the point otherwise? And trying to // run a ticker without being attached will crash! if (n.notification.tickerText != null && mStatusBarView.getWindowToken() != null) { if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) { mTicker.addEntry(n); } } } private class MyTicker extends Ticker { private class MyTicker extends Ticker { MyTicker(Context context, StatusBarView sb) { MyTicker(Context context, StatusBarView sb) { super(context, sb); super(context, sb); Loading
packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +6 −3 Original line number Original line Diff line number Diff line Loading @@ -69,6 +69,7 @@ public class StatusBarIconView extends AnimatedImageView { Drawable drawable = getIcon(icon); Drawable drawable = getIcon(icon); if (drawable == null) { if (drawable == null) { mError = true; mError = true; Slog.w(PhoneStatusBarService.TAG, "No icon ID for slot " + mSlot); break error; break error; } } setImageDrawable(drawable); setImageDrawable(drawable); Loading @@ -86,6 +87,10 @@ public class StatusBarIconView extends AnimatedImageView { } } } } private Drawable getIcon(StatusBarIcon icon) { return getIcon(getContext(), icon); } /** /** * Returns the right icon to use for this item, respecting the iconId and * Returns the right icon to use for this item, respecting the iconId and * iconPackage (if set) * iconPackage (if set) Loading @@ -94,8 +99,7 @@ public class StatusBarIconView extends AnimatedImageView { * @return Drawable for this item, or null if the package or item could not * @return Drawable for this item, or null if the package or item could not * be found * be found */ */ private Drawable getIcon(StatusBarIcon icon) { public static Drawable getIcon(Context context, StatusBarIcon icon) { Context context = getContext(); Resources r = null; Resources r = null; if (icon.iconPackage != null) { if (icon.iconPackage != null) { Loading @@ -110,7 +114,6 @@ public class StatusBarIconView extends AnimatedImageView { } } if (icon.iconId == 0) { if (icon.iconId == 0) { Slog.w(PhoneStatusBarService.TAG, "No icon ID for slot " + mSlot); return null; return null; } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/Ticker.java +45 −18 Original line number Original line Diff line number Diff line Loading @@ -33,14 +33,24 @@ import android.widget.ImageSwitcher; import java.util.ArrayList; import java.util.ArrayList; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.statusbar.StatusBarNotification; import com.android.internal.statusbar.StatusBarNotification; import com.android.internal.util.CharSequences; import com.android.systemui.R; import com.android.systemui.R; public abstract class Ticker { public abstract class Ticker { private static final int TICKER_SEGMENT_DELAY = 3000; private static final int TICKER_SEGMENT_DELAY = 3000; private Context mContext; private Handler mHandler = new Handler(); private ArrayList<Segment> mSegments = new ArrayList(); private TextPaint mPaint; private View mTickerView; private ImageSwitcher mIconSwitcher; private TextSwitcher mTextSwitcher; private final class Segment { private final class Segment { StatusBarNotification notificationData; StatusBarNotification notification; Drawable icon; Drawable icon; CharSequence text; CharSequence text; int current; int current; Loading Loading @@ -117,7 +127,7 @@ public abstract class Ticker { } } Segment(StatusBarNotification n, Drawable icon, CharSequence text) { Segment(StatusBarNotification n, Drawable icon, CharSequence text) { this.notificationData = n; this.notification = n; this.icon = icon; this.icon = icon; this.text = text; this.text = text; int index = 0; int index = 0; Loading @@ -131,14 +141,8 @@ public abstract class Ticker { } } }; }; private Handler mHandler = new Handler(); private ArrayList<Segment> mSegments = new ArrayList(); private TextPaint mPaint; private View mTickerView; private ImageSwitcher mIconSwitcher; private TextSwitcher mTextSwitcher; Ticker(Context context, StatusBarView sb) { Ticker(Context context, StatusBarView sb) { mContext = context; mTickerView = sb.findViewById(R.id.ticker); mTickerView = sb.findViewById(R.id.ticker); mIconSwitcher = (ImageSwitcher)sb.findViewById(R.id.tickerIcon); mIconSwitcher = (ImageSwitcher)sb.findViewById(R.id.tickerIcon); Loading @@ -158,20 +162,34 @@ public abstract class Ticker { mPaint = text.getPaint(); mPaint = text.getPaint(); } } void addEntry(StatusBarNotification n, Drawable icon, CharSequence text) { void addEntry(StatusBarNotification n) { int initialCount = mSegments.size(); int initialCount = mSegments.size(); Segment newSegment = new Segment(n, icon, text); // If what's being displayed has the same text and icon, just drop it // (which will let the current one finish, this happens when apps do // a notification storm). if (initialCount > 0) { final Segment seg = mSegments.get(0); if (n.pkg.equals(seg.notification.pkg) && n.notification.icon == seg.notification.notification.icon && n.notification.iconLevel == seg.notification.notification.iconLevel && CharSequences.equals(seg.notification.notification.tickerText, n.notification.tickerText)) { return; } } final Drawable icon = StatusBarIconView.getIcon(mContext, new StatusBarIcon(n.pkg, n.notification.icon, n.notification.iconLevel, 0)); final Segment newSegment = new Segment(n, icon, n.notification.tickerText); // prune out any preexisting ones for this notification, but not the current one. // If there's already a notification schedule for this package and id, remove it. // let that finish, even if it's the same id for (int i=0; i<initialCount; i++) { for (int i=1; i<initialCount; i++) { Segment seg = mSegments.get(i); Segment seg = mSegments.get(i); if (n.id == seg.notificationData.id && n.pkg.equals(seg.notificationData.pkg)) { if (n.id == seg.notification.id && n.pkg.equals(seg.notification.pkg)) { // just update that one to use this new data instead // just update that one to use this new data instead mSegments.set(i, newSegment); mSegments.remove(i); // and since we know initialCount != 0, just return return ; } } } } Loading @@ -194,6 +212,15 @@ public abstract class Ticker { } } } } void removeEntry(StatusBarNotification n) { for (int i=mSegments.size()-1; i>=0; i--) { Segment seg = mSegments.get(i); if (n.id == seg.notification.id && n.pkg.equals(seg.notification.pkg)) { mSegments.remove(i); } } } void halt() { void halt() { mHandler.removeCallbacks(mAdvanceTicker); mHandler.removeCallbacks(mAdvanceTicker); mSegments.clear(); mSegments.clear(); Loading