Get the ticker working again.
Change-Id: Idb7e456bc302578c3866448334eb0ebf0ba235d4
This commit is contained in:
@@ -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;
|
||||||
@@ -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();
|
||||||
@@ -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();
|
||||||
@@ -409,14 +408,16 @@ 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);
|
||||||
|
|
||||||
// Cancel the ticker if it's still running
|
if (old != null) {
|
||||||
// TODO
|
// Cancel the ticker if it's still running
|
||||||
|
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) {
|
||||||
@@ -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() {
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -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)
|
||||||
@@ -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) {
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -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;
|
||||||
@@ -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);
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// prune out any preexisting ones for this notification, but not the current one.
|
final Drawable icon = StatusBarIconView.getIcon(mContext,
|
||||||
// let that finish, even if it's the same id
|
new StatusBarIcon(n.pkg, n.notification.icon, n.notification.iconLevel, 0));
|
||||||
for (int i=1; i<initialCount; i++) {
|
final Segment newSegment = new Segment(n, icon, n.notification.tickerText);
|
||||||
|
|
||||||
|
// If there's already a notification schedule for this package and id, remove it.
|
||||||
|
for (int i=0; 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 ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user