Tablet ticker.
Change-Id: Ia3db5cc29eac1703123de3e1c6dc7c22e7d024eb
diff --git a/api/current.xml b/api/current.xml
index c581f34..374e26f 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -32558,6 +32558,27 @@
visibility="public"
>
</field>
+<field name="tickerIcons"
+ type="android.graphics.Bitmap[]"
+ transient="false"
+ volatile="false"
+ value="null"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="tickerSubtitle"
+ type="java.lang.CharSequence"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="tickerText"
type="java.lang.CharSequence"
transient="false"
@@ -32568,6 +32589,16 @@
visibility="public"
>
</field>
+<field name="tickerTitle"
+ type="java.lang.CharSequence"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="vibrate"
type="long[]"
transient="false"
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index da000e5..e602518 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -21,6 +21,7 @@
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
+import android.graphics.Bitmap;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Parcel;
@@ -124,11 +125,47 @@
/**
* Text to scroll across the screen when this item is added to
- * the status bar.
+ * the status bar on large and smaller devices.
+ *
+ * <p>This field is provided separately from the other ticker fields
+ * both for compatibility and to allow an application to choose different
+ * text for when the text scrolls in and when it is displayed all at once
+ * in conjunction with one or more icons.
+ *
+ * @see #tickerTitle
+ * @see #tickerSubtitle
+ * @see #tickerIcons
*/
public CharSequence tickerText;
/**
+ * The title line for the ticker over a the fat status bar on xlarge devices.
+ *
+ * @see #tickerText
+ * @see #tickerSubtitle
+ * @see #tickerIcons
+ */
+ public CharSequence tickerTitle;
+
+ /**
+ * The subtitle line for the ticker over a the fat status bar on xlarge devices.
+ *
+ * @see #tickerText
+ * @see #tickerTitle
+ * @see #tickerIcons
+ */
+ public CharSequence tickerSubtitle;
+
+ /**
+ * The icons to show to the left of the other ticker fields.
+ *
+ * @see #tickerText
+ * @see #tickerTitle
+ * @see #tickerSubtitle
+ */
+ public Bitmap[] tickerIcons;
+
+ /**
* The view that will represent this notification in the expanded status bar.
*/
public RemoteViews contentView;
@@ -347,6 +384,21 @@
tickerText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
}
if (parcel.readInt() != 0) {
+ tickerTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
+ }
+ if (parcel.readInt() != 0) {
+ tickerSubtitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
+ }
+ final int tickerIconCount = parcel.readInt();
+ if (tickerIconCount >= 0) {
+ tickerIcons = new Bitmap[tickerIconCount];
+ for (int i=0; i<tickerIconCount; i++) {
+ if (parcel.readInt() != 0) {
+ tickerIcons[i] = Bitmap.CREATOR.createFromParcel(parcel);
+ }
+ }
+ }
+ if (parcel.readInt() != 0) {
contentView = RemoteViews.CREATOR.createFromParcel(parcel);
}
defaults = parcel.readInt();
@@ -382,6 +434,19 @@
if (this.tickerText != null) {
that.tickerText = this.tickerText.toString();
}
+ if (this.tickerTitle != null) {
+ that.tickerTitle = this.tickerTitle.toString();
+ }
+ if (this.tickerSubtitle != null) {
+ that.tickerSubtitle = this.tickerSubtitle.toString();
+ }
+ if (this.tickerIcons != null) {
+ final int N = this.tickerIcons.length;
+ that.tickerIcons = new Bitmap[N];
+ for (int i=0; i<N; i++) {
+ that.tickerIcons[i] = Bitmap.createBitmap(this.tickerIcons[i]);
+ }
+ }
if (this.contentView != null) {
that.contentView = this.contentView.clone();
}
@@ -438,6 +503,32 @@
} else {
parcel.writeInt(0);
}
+ if (tickerTitle != null) {
+ parcel.writeInt(1);
+ TextUtils.writeToParcel(tickerTitle, parcel, flags);
+ } else {
+ parcel.writeInt(0);
+ }
+ if (tickerSubtitle != null) {
+ parcel.writeInt(1);
+ TextUtils.writeToParcel(tickerSubtitle, parcel, flags);
+ } else {
+ parcel.writeInt(0);
+ }
+ if (tickerIcons != null) {
+ final int N = tickerIcons.length;
+ parcel.writeInt(N);
+ for (int i=0; i<N; i++) {
+ if (tickerIcons[i] != null) {
+ parcel.writeInt(1);
+ tickerIcons[i].writeToParcel(parcel, flags);
+ } else {
+ parcel.writeInt(0);
+ }
+ }
+ } else {
+ parcel.writeInt(-1);
+ }
if (contentView != null) {
parcel.writeInt(1);
contentView.writeToParcel(parcel, 0);
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index e0b34cc..ba7029d9 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -1,21 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/* apps/common/assets/default/default/skins/StatusBar.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
-->
<!-- android:background="@drawable/status_bar_closed_default_background" -->
@@ -65,41 +62,16 @@
</com.android.systemui.statusbar.tablet.NotificationIconArea>
- <LinearLayout android:id="@+id/ticker"
- android:layout_width="300dip"
+ <FrameLayout
+ android:id="@+id/ticker"
+ android:layout_width="wrap_content"
android:layout_height="match_parent"
+ android:layout_alignParentLeft="true"
+ android:layout_toLeftOf="@+id/systemInfo"
android:paddingLeft="6dip"
- android:animationCache="false"
- android:layout_alignLeft="@id/notificationIcons"
- android:layout_alignTop="@id/notificationIcons"
- android:orientation="horizontal"
- android:visibility="gone"
- >
- <ImageView android:id="@+id/tickerIcon"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_marginRight="8dip"
- />
- <com.android.systemui.statusbar.TickerView android:id="@+id/tickerText"
- android:layout_width="0dip"
- android:layout_weight="1"
- android:layout_height="wrap_content"
- android:paddingTop="2dip"
- android:paddingRight="10dip">
- <TextView
- android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:singleLine="true"
- />
- <TextView
- android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:singleLine="true"
- />
- </com.android.systemui.statusbar.TickerView>
- </LinearLayout>
+ android:gravity="center_vertical"
+ android:animateLayoutChanges="true"
+ />
<include layout="@layout/status_bar_center"
android:layout_width="256dip"
diff --git a/packages/SystemUI/res/layout-xlarge/ticker.xml b/packages/SystemUI/res/layout-xlarge/ticker.xml
new file mode 100644
index 0000000..c8d855f
--- /dev/null
+++ b/packages/SystemUI/res/layout-xlarge/ticker.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:background="#ff000000"
+ >
+
+ <LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_gravity="center_vertical"
+ android:orientation="vertical"
+ android:paddingLeft="12dp"
+ >
+
+ <TextView android:id="@+id/title"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textStyle="bold"
+ android:maxLines="1"
+ />
+ <TextView android:id="@+id/subtitle"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxLines="1"
+ />
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/ticker_compat.xml b/packages/SystemUI/res/layout-xlarge/ticker_compat.xml
new file mode 100644
index 0000000..79c7543
--- /dev/null
+++ b/packages/SystemUI/res/layout-xlarge/ticker_compat.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:background="#ff000000"
+ >
+
+ <TextView android:id="@+id/text"
+ android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_vertical"
+ android:layout_marginLeft="12dp"
+ android:gravity="center_vertical"
+ android:maxLines="2"
+ />
+
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/ticker_icon.xml b/packages/SystemUI/res/layout-xlarge/ticker_icon.xml
new file mode 100644
index 0000000..9efa987
--- /dev/null
+++ b/packages/SystemUI/res/layout-xlarge/ticker_icon.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+
+<ImageView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="30dp"
+ android:layout_height="30dp"
+ android:layout_gravity="center"
+ android:layout_marginLeft="6dp"
+ />
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
index 5ba1fab..c4819a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
@@ -18,6 +18,7 @@
import android.app.ActivityManagerNative;
import android.app.PendingIntent;
+import android.app.Notification;
import android.app.StatusBarManager;
import android.content.Context;
import android.content.Intent;
@@ -28,6 +29,7 @@
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
+import android.text.TextUtils;
import android.util.Slog;
import android.view.animation.AnimationUtils;
import android.view.Gravity;
@@ -36,6 +38,7 @@
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.WindowManagerImpl;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RemoteViews;
@@ -81,8 +84,8 @@
NotificationIconArea.IconLayout mIconLayout;
- KickerController mKicker;
- View mKickerView;
+ TabletTicker mTicker;
+ View mTickerView;
boolean mTicking;
boolean mExpandedVisible;
@@ -163,7 +166,7 @@
// where the icons go
mIconLayout = (NotificationIconArea.IconLayout) sb.findViewById(R.id.icons);
- mKicker = new KickerController((Context)this, mStatusBarView);
+ mTicker = new TabletTicker((Context)this, (FrameLayout)sb.findViewById(R.id.ticker));
// System info (center)
mBatteryMeter = (ImageView) sb.findViewById(R.id.battery);
@@ -274,7 +277,7 @@
} catch (PendingIntent.CanceledException e) {
}
} else {
- // tick()
+ tick(notification);
}
}
@@ -344,7 +347,7 @@
removeNotificationViews(key);
addNotificationViews(key, notification);
}
- // TODO: kicker; immersive mode
+ // TODO: ticker; immersive mode
}
public void removeNotification(IBinder key) {
@@ -368,7 +371,7 @@
if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
if (mTicking) {
- mKicker.halt();
+ mTicker.halt();
} else {
mNotificationIconArea.setVisibility(View.INVISIBLE);
}
@@ -381,7 +384,7 @@
} else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
Slog.d(TAG, "DISABLE_NOTIFICATION_TICKER: yes");
- mKicker.halt();
+ mTicker.halt();
}
}
*/
@@ -405,7 +408,7 @@
Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
if (mTicking) {
mNotificationIconArea.setVisibility(View.INVISIBLE);
- mKicker.halt();
+ mTicker.halt();
} else {
mNotificationIconArea.setVisibility(View.INVISIBLE);
}
@@ -417,65 +420,31 @@
}
} else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
if (mTicking && (net & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
- mKicker.halt();
+ mTicker.halt();
}
}
*/
}
+ private boolean hasTicker(Notification n) {
+ return !TextUtils.isEmpty(n.tickerText)
+ || !TextUtils.isEmpty(n.tickerTitle)
+ || !TextUtils.isEmpty(n.tickerSubtitle);
+ }
+
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 (hasTicker(n.notification) && mStatusBarView.getWindowToken() != null) {
if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
| StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
- mKicker.addEntry(n);
+ mTicker.add(n);
}
}
}
- private class KickerController {
- View mView;
- ImageView mKickerIcon;
- TextSwitcher mKickerText;
-
- public KickerController(Context context, View sb) {
- mView = sb.findViewById(R.id.ticker);
- mKickerIcon = (ImageView) mView.findViewById(R.id.tickerIcon);
- mKickerText = (TextSwitcher) mView.findViewById(R.id.tickerText);
- }
-
- public void halt() {
- tickerHalting();
- }
-
- public void addEntry(StatusBarNotification n) {
- mKickerIcon.setImageResource(n.notification.icon);
- mKickerText.setCurrentText(n.notification.tickerText);
- tickerStarting();
- }
-
- public void tickerStarting() {
- mTicking = true;
- mIconLayout.setVisibility(View.GONE);
- mKickerView.setVisibility(View.VISIBLE);
- }
-
- public void tickerDone() {
- mIconLayout.setVisibility(View.VISIBLE);
- mKickerView.setVisibility(View.GONE);
- mTicking = false;
- }
-
- public void tickerHalting() {
- mIconLayout.setVisibility(View.VISIBLE);
- mKickerView.setVisibility(View.GONE);
- mTicking = false;
- }
- }
-
public void animateExpand() {
mHandler.removeMessages(H.MSG_OPEN_NOTIFICATION_PANEL);
mHandler.sendEmptyMessage(H.MSG_OPEN_NOTIFICATION_PANEL);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
new file mode 100644
index 0000000..7ac7919
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.tablet;
+
+import android.app.Notification;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Slog;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.internal.statusbar.StatusBarNotification;
+
+import com.android.systemui.R;
+
+import java.util.Arrays;
+
+public class TabletTicker extends Handler {
+ private static final String TAG = "StatusBar.TabletTicker";
+
+ private static final int MSG_ADVANCE = 1;
+
+ private static final int ADVANCE_DELAY = 5000; // 5 seconds
+
+ private Context mContext;
+ private FrameLayout mParent;
+
+ private StatusBarNotification mCurrentNotification;
+ private View mCurrentView;
+
+ private StatusBarNotification[] mQueue;
+ private int mQueuePos;
+
+ public TabletTicker(Context context, FrameLayout parent) {
+ mContext = context;
+ mParent = parent;
+
+ // TODO: Make this a configuration value.
+ // 3 is enough to let us see most cases, but not get so far behind that it's annoying.
+ int mQueuePos = 0;
+ mQueue = new StatusBarNotification[3];
+ }
+
+ public void add(StatusBarNotification notification) {
+ if (false) {
+ Slog.d(TAG, "add mCurrentNotification=" + mCurrentNotification
+ + " mQueuePos=" + mQueuePos + " mQueue=" + Arrays.toString(mQueue));
+ }
+ mQueue[mQueuePos] = notification;
+
+ // If nothing is running now, start the next one
+ if (mCurrentNotification == null) {
+ sendEmptyMessage(MSG_ADVANCE);
+ }
+
+ if (mQueuePos < mQueue.length - 1) {
+ mQueuePos++;
+ }
+ }
+
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_ADVANCE:
+ advance();
+ break;
+ }
+ }
+
+ private void advance() {
+ // Out with the old...
+ if (mCurrentView != null) {
+ mParent.removeView(mCurrentView);
+ mCurrentView = null;
+ mCurrentNotification = null;
+ }
+
+ // In with the new...
+ final StatusBarNotification next = dequeue();
+ if (next != null) {
+ mCurrentNotification = next;
+ mCurrentView = makeTickerView(next);
+ mParent.addView(mCurrentView);
+ sendEmptyMessageDelayed(MSG_ADVANCE, ADVANCE_DELAY);
+ }
+ }
+
+ private StatusBarNotification dequeue() {
+ StatusBarNotification notification = mQueue[0];
+ if (false) {
+ Slog.d(TAG, "dequeue mQueuePos=" + mQueuePos + " mQueue=" + Arrays.toString(mQueue));
+ }
+ final int N = mQueuePos;
+ for (int i=0; i<N; i++) {
+ mQueue[i] = mQueue[i+1];
+ }
+ mQueue[N] = null;
+ if (mQueuePos > 0) {
+ mQueuePos--;
+ }
+ return notification;
+ }
+
+ private View makeTickerView(StatusBarNotification notification) {
+ final Notification n = notification.notification;
+
+ LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+
+ int layoutId;
+ ViewGroup group;
+ if (n.tickerTitle != null || n.tickerSubtitle != null) {
+ group = (ViewGroup)inflater.inflate(R.layout.ticker, mParent, false);
+ if (n.tickerTitle != null) {
+ final TextView title = (TextView)group.findViewById(R.id.title);
+ title.setText(n.tickerTitle);
+ }
+ if (n.tickerSubtitle != null) {
+ final TextView subtitle = (TextView)group.findViewById(R.id.subtitle);
+ subtitle.setText(n.tickerSubtitle);
+ }
+ } else {
+ group = (ViewGroup)inflater.inflate(R.layout.ticker_compat, mParent, false);
+ TextView tv = (TextView)group.findViewById(R.id.text);
+ tv.setText(n.tickerText);
+ }
+
+ // No more than 2 icons.
+ if (n.tickerIcons != null) {
+ int N = n.tickerIcons.length;
+ if (N > 2) {
+ N = 2;
+ }
+ for (int i=N-1; i>= 0; i--) {
+ Bitmap b = n.tickerIcons[i];
+ if (b != null) {
+ ImageView iv = (ImageView)inflater.inflate(R.layout.ticker_icon, group, false);
+ iv.setImageBitmap(b);
+ group.addView(iv, 0);
+ }
+ }
+ }
+
+ return group;
+ }
+}
+
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 16b3001..7b6e2d2 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -16,12 +16,14 @@
package com.android.statusbartest;
+import android.app.Notification;
+import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.ContentResolver;
import android.content.Intent;
-import android.app.Notification;
-import android.app.NotificationManager;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
import android.os.Environment;
import android.os.Vibrator;
import android.os.Handler;
@@ -77,6 +79,112 @@
}
},
+ new Test("Cancel #1") {
+ public void run()
+ {
+ mNM.cancel(1);
+ }
+ },
+
+ new Test("Ticker 1 line") {
+ public void run() {
+ Notification n = new Notification(R.drawable.icon1, "tick tick tick",
+ mActivityCreateTime);
+ n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
+ "This is a notification!!!", makeIntent());
+ mNM.notify(1, n);
+ }
+ },
+
+ new Test("Ticker 1 line & icon") {
+ public void run() {
+ Notification n = new Notification(R.drawable.icon1, "tick tick tick",
+ mActivityCreateTime);
+ n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
+ "This is a notification!!!", makeIntent());
+ n.tickerIcons = new Bitmap[1];
+ n.tickerIcons[0] = loadBitmap(R.drawable.icon3);
+ mNM.notify(1, n);
+ }
+ },
+
+ new Test("Ticker 2 lines") {
+ public void run() {
+ Notification n = new Notification(R.drawable.icon1, "tick tick tick\ntock tock",
+ mActivityCreateTime);
+ n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
+ "This is a notification!!!", makeIntent());
+ mNM.notify(1, n);
+ }
+ },
+
+ new Test("Ticker title") {
+ public void run() {
+ Notification n = new Notification(R.drawable.icon1, null,
+ mActivityCreateTime);
+ n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
+ "This is a notification!!!", makeIntent());
+ n.tickerTitle = "This is a title";
+ mNM.notify(1, n);
+ }
+ },
+
+ new Test("Ticker subtitle") {
+ public void run() {
+ Notification n = new Notification(R.drawable.icon1, null,
+ mActivityCreateTime);
+ n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
+ "This is a notification!!!", makeIntent());
+ n.tickerSubtitle = "and a subtitle";
+ mNM.notify(1, n);
+ }
+ },
+
+ new Test("Ticker title & subtitle") {
+ public void run() {
+ Notification n = new Notification(R.drawable.icon1, null,
+ mActivityCreateTime);
+ n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
+ "This is a notification!!!", makeIntent());
+ n.tickerTitle = "This is a title it is really really longggggg long long long long";
+ n.tickerSubtitle = "and a subtitle it is really really longggggg long long long long long long long long long long long long long long long long";
+ mNM.notify(1, n);
+ }
+ },
+
+ new Test("Ticker text, title & subtitle") {
+ public void run() {
+ Notification n = new Notification(R.drawable.icon1, "not visible",
+ mActivityCreateTime);
+ n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
+ "This is a notification!!!", makeIntent());
+ n.tickerTitle = "This is a title";
+ n.tickerSubtitle = "and a subtitle";
+ mNM.notify(1, n);
+ }
+ },
+
+ new Test("Ticker title, subtitle & 2 icons") {
+ public void run() {
+ Notification n = new Notification(R.drawable.icon1, null,
+ mActivityCreateTime);
+ n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
+ "This is a notification!!!", makeIntent());
+ n.tickerTitle = "This is a title";
+ n.tickerSubtitle = "and a subtitle";
+
+ n.tickerIcons = new Bitmap[2];
+ n.tickerIcons[0] = loadBitmap(R.drawable.icon3);
+ n.tickerIcons[1] = loadBitmap(R.drawable.app_gmail);
+
+ mNM.notify(1, n);
+ /*
+ n.tickerIcons[0].recycle();
+ n.tickerIcons[1].recycle();
+ */
+ }
+ },
+
new Test("No view") {
public void run() {
Notification n = new Notification(R.drawable.icon1, "No view",
@@ -479,7 +587,7 @@
new Test("Persistent #3") {
public void run() {
- Notification n = new Notification(R.drawable.icon2, "tock tock tock",
+ Notification n = new Notification(R.drawable.icon2, "tock tock tock\nmooooo",
System.currentTimeMillis());
n.setLatestEventInfo(NotificationTestList.this, "Persistent #3",
"Notify me!!!", makeIntent());
@@ -701,5 +809,10 @@
time, label, "" + new java.util.Date(time), null));
}
+
+ Bitmap loadBitmap(int resId) {
+ BitmapDrawable bd = (BitmapDrawable)getResources().getDrawable(resId);
+ return Bitmap.createBitmap(bd.getBitmap());
+ }
}