summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java10
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java9
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBarService.aidl4
-rw-r--r--core/res/AndroidManifest.xml10
-rw-r--r--core/res/res/drawable/status_bar_item_background.xml2
-rw-r--r--core/res/res/values/arrays.xml24
-rw-r--r--core/res/res/values/config.xml30
-rw-r--r--core/res/res/values/strings.xml5
-rw-r--r--include/private/surfaceflinger/SharedBufferStack.h16
-rw-r--r--include/surfaceflinger/Surface.h6
-rw-r--r--libs/surfaceflinger/Layer.cpp48
-rw-r--r--libs/surfaceflinger/Layer.h11
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.cpp22
-rw-r--r--libs/surfaceflinger_client/SharedBufferStack.cpp4
-rw-r--r--libs/surfaceflinger_client/Surface.cpp55
-rw-r--r--libs/surfaceflinger_client/SurfaceComposerClient.cpp4
-rw-r--r--libs/ui/GraphicBuffer.cpp3
-rw-r--r--media/jni/android_media_MediaRecorder.cpp4
-rw-r--r--packages/SystemUI/AndroidManifest.xml14
-rw-r--r--packages/SystemUI/res/drawable-hdpi/status_bar_item_background_focus.9.pngbin1657 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/status_bar_item_background_normal.9.pngbin197 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/status_bar_item_background_pressed.9.pngbin1531 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/status_bar_item_background_focus.9.pngbin11006 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/status_bar_item_background_normal.9.pngbin186 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/status_bar_item_background_pressed.9.pngbin11006 -> 0 bytes
-rw-r--r--packages/SystemUI/res/layout/status_bar_latest_event.xml (renamed from core/res/res/layout/status_bar_latest_event.xml)8
-rw-r--r--packages/SystemUI/res/values/arrays.xml28
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java83
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java57
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStarter.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java (renamed from services/java/com/android/server/status/StorageNotification.java)9
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java (renamed from services/java/com/android/server/status/UsbStorageActivity.java)2
-rwxr-xr-xpolicy/com/android/internal/policy/impl/PhoneWindowManager.java8
-rw-r--r--services/java/com/android/server/DevicePolicyManagerService.java7
-rw-r--r--services/java/com/android/server/InputMethodManagerService.java2
-rwxr-xr-xservices/java/com/android/server/NotificationManagerService.java30
-rw-r--r--services/java/com/android/server/StatusBarManagerService.java (renamed from services/java/com/android/server/status/StatusBarManagerService.java)65
-rw-r--r--services/java/com/android/server/SystemServer.java1
-rw-r--r--services/java/com/android/server/WindowManagerService.java98
-rw-r--r--services/java/com/android/server/status/LatestItemView.java34
-rwxr-xr-xservices/java/com/android/server/status/package.html5
-rw-r--r--tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java63
-rw-r--r--tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java17
45 files changed, 489 insertions, 355 deletions
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index 8263e75..39b3a20 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -175,6 +175,11 @@ public final class Bmgr {
private void doTransport() {
try {
String which = nextArg();
+ if (which == null) {
+ showUsage();
+ return;
+ }
+
String old = mBmgr.selectBackupTransport(which);
if (old == null) {
System.out.println("Unknown transport '" + which
@@ -318,6 +323,11 @@ public final class Bmgr {
private void doRestore() {
String arg = nextArg();
+ if (arg == null) {
+ showUsage();
+ return;
+ }
+
if (arg.indexOf('.') >= 0) {
// it's a package name
doRestorePackage(arg);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 35e7ee6..296d70a4 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -78,6 +78,15 @@ public class DevicePolicyManager {
= "android.app.action.ADD_DEVICE_ADMIN";
/**
+ * Activity action: send when any policy admin changes a policy.
+ * This is generally used to find out when a new policy is in effect.
+ *
+ * @hide
+ */
+ public static final String ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
+ = "android.app.action.DEVICE_POLICY_MANAGER_STATE_CHANGED";
+
+ /**
* The ComponentName of the administrator component.
*
* @see #ACTION_ADD_DEVICE_ADMIN
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 1f25b37..045c24f 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -32,9 +32,11 @@ interface IStatusBarService
void removeIcon(String slot);
// ---- Methods below are for use by the status bar policy services ----
+ // You need the STATUS_BAR_SERVICE permission
void registerStatusBar(IStatusBar callbacks, out StatusBarIconList iconList,
out List<IBinder> notificationKeys, out List<StatusBarNotification> notifications);
- void visibilityChanged(boolean visible);
+ void onPanelRevealed();
void onNotificationClick(String pkg, String tag, int id);
+ void onNotificationError(String pkg, String tag, int id, String message);
void onClearAllNotifications();
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 1fcf186..aff9453 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -908,6 +908,13 @@
android:description="@string/permdesc_statusBar"
android:protectionLevel="signatureOrSystem" />
+ <!-- Allows an application to be the status bar. Currently used only by SystemUI.apk
+ @hide -->
+ <permission android:name="android.permission.STATUS_BAR_SERVICE"
+ android:label="@string/permlab_statusBarService"
+ android:description="@string/permdesc_statusBarService"
+ android:protectionLevel="signature" />
+
<!-- Allows an application to force a BACK operation on whatever is the
top activity. -->
<permission android:name="android.permission.FORCE_BACK"
@@ -1269,9 +1276,6 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
- <activity android:name="com.android.server.status.UsbStorageActivity"
- android:excludeFromRecents="true">
- </activity>
<activity android:name="com.android.internal.app.ExternalMediaFormatActivity"
android:theme="@style/Theme.Dialog.Alert"
android:excludeFromRecents="true">
diff --git a/core/res/res/drawable/status_bar_item_background.xml b/core/res/res/drawable/status_bar_item_background.xml
index 088389b..425a502 100644
--- a/core/res/res/drawable/status_bar_item_background.xml
+++ b/core/res/res/drawable/status_bar_item_background.xml
@@ -16,7 +16,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
- android:drawable="@drawable/status_bar_item_background_pressed" />
+ android:drawable="@drawable/status_bar_item_background_pressed" />
<item android:state_focused="true" android:state_pressed="false"
android:drawable="@drawable/status_bar_item_background_focus" />
<item android:drawable="@drawable/status_bar_item_background_normal" />
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 0493756..aeee8af 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -117,28 +117,4 @@
<item>3</item>
</integer-array>
- <!-- Do not translate. Defines the slots for the right-hand side icons. That is to say, the
- icons in the status bar that are not notifications. -->
- <string-array name="status_bar_icon_order">
- <item><xliff:g id="id">ime</xliff:g></item>
- <item><xliff:g id="id">sync_failing</xliff:g></item>
- <item><xliff:g id="id">sync_active</xliff:g></item>
- <item><xliff:g id="id">gps</xliff:g></item>
- <item><xliff:g id="id">bluetooth</xliff:g></item>
- <item><xliff:g id="id">tty</xliff:g></item>
- <item><xliff:g id="id">speakerphone</xliff:g></item>
- <item><xliff:g id="id">mute</xliff:g></item>
- <item><xliff:g id="id">volume</xliff:g></item>
- <item><xliff:g id="id">tty</xliff:g></item>
- <item><xliff:g id="id">wifi</xliff:g></item>
- <item><xliff:g id="id">cdma_eri</xliff:g></item>
- <item><xliff:g id="id">data_connection</xliff:g></item>
- <item><xliff:g id="id">phone_evdo_signal</xliff:g></item>
- <item><xliff:g id="id">phone_signal</xliff:g></item>
- <item><xliff:g id="id">battery</xliff:g></item>
- <item><xliff:g id="id">alarm_clock</xliff:g></item>
- <item><xliff:g id="id">secure</xliff:g></item>
- <item><xliff:g id="id">clock</xliff:g></item>
- </string-array>
-
</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 1946388..cffcd1d 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -19,7 +19,35 @@
<!-- These resources are around just to allow their values to be customized
for different hardware and product builds. -->
-<resources>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Component to be used as the status bar service. Must implement the IStatusBar
+ interface. This name is in the ComponentName flattened format (package/class) -->
+ <string name="config_statusBarComponent">com.android.systemui/com.android.systemui.statusbar.PhoneStatusBarService</string>
+
+ <!-- Do not translate. Defines the slots for the right-hand side icons. That is to say, the
+ icons in the status bar that are not notifications. -->
+ <string-array name="config_statusBarIcons">
+ <item><xliff:g id="id">ime</xliff:g></item>
+ <item><xliff:g id="id">sync_failing</xliff:g></item>
+ <item><xliff:g id="id">sync_active</xliff:g></item>
+ <item><xliff:g id="id">gps</xliff:g></item>
+ <item><xliff:g id="id">bluetooth</xliff:g></item>
+ <item><xliff:g id="id">tty</xliff:g></item>
+ <item><xliff:g id="id">speakerphone</xliff:g></item>
+ <item><xliff:g id="id">mute</xliff:g></item>
+ <item><xliff:g id="id">volume</xliff:g></item>
+ <item><xliff:g id="id">tty</xliff:g></item>
+ <item><xliff:g id="id">wifi</xliff:g></item>
+ <item><xliff:g id="id">cdma_eri</xliff:g></item>
+ <item><xliff:g id="id">data_connection</xliff:g></item>
+ <item><xliff:g id="id">phone_evdo_signal</xliff:g></item>
+ <item><xliff:g id="id">phone_signal</xliff:g></item>
+ <item><xliff:g id="id">battery</xliff:g></item>
+ <item><xliff:g id="id">alarm_clock</xliff:g></item>
+ <item><xliff:g id="id">secure</xliff:g></item>
+ <item><xliff:g id="id">clock</xliff:g></item>
+ </string-array>
+
<!-- Flag indicating whether the surface flinger has limited
alpha compositing functionality in hardware. If set, the window
manager will disable alpha trasformation in animations where not
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index e7f892a..fc1db18 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -393,6 +393,11 @@
the status bar or add and remove system icons.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_statusBarService">status bar</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_statusBarService">Allows the application to be the status bar.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_expandStatusBar">expand/collapse status bar</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_expandStatusBar">Allows application to
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index c11c855..633b543 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -43,15 +43,6 @@ namespace android {
* unless they are in use by the server, which is only the case for the last
* dequeue-able buffer. When these various conditions are not met, the caller
* waits until the condition is met.
- *
- *
- * CAVEATS:
- *
- * In the current implementation there are several limitations:
- * - buffers must be locked in the same order they've been dequeued
- * - buffers must be enqueued in the same order they've been locked
- * - dequeue() is not reentrant
- * - no error checks are done on the condition above
*
*/
@@ -269,7 +260,9 @@ private:
// ----------------------------------------------------------------------------
-class SharedBufferServer : public SharedBufferBase
+class SharedBufferServer
+ : public SharedBufferBase,
+ public LightRefBase<SharedBufferServer>
{
public:
SharedBufferServer(SharedClient* sharedClient, int surface, int num,
@@ -290,6 +283,9 @@ public:
private:
+ friend class LightRefBase<SharedBufferServer>;
+ ~SharedBufferServer();
+
/*
* BufferList is basically a fixed-capacity sorted-vector of
* unsigned 5-bits ints using a 32-bits int as storage.
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index ac01ce5..f333911 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -60,7 +60,6 @@ public:
static bool isSameSurface(
const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs);
- SurfaceID ID() const { return mToken; }
uint32_t getFlags() const { return mFlags; }
uint32_t getIdentity() const { return mIdentity; }
@@ -145,6 +144,9 @@ public:
uint32_t reserved[2];
};
+ static status_t writeToParcel(
+ const sp<Surface>& control, Parcel* parcel);
+
static sp<Surface> readFromParcel(
const Parcel& data, const sp<Surface>& other);
@@ -153,7 +155,6 @@ public:
}
bool isValid();
- SurfaceID ID() const { return mToken; }
uint32_t getFlags() const { return mFlags; }
uint32_t getIdentity() const { return mIdentity; }
@@ -267,7 +268,6 @@ private:
SharedBufferClient* mSharedBufferClient;
status_t mInitCheck;
sp<ISurface> mSurface;
- SurfaceID mToken;
uint32_t mIdentity;
PixelFormat mFormat;
uint32_t mFlags;
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index a94fdd4..e7247bd 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -76,15 +76,18 @@ Layer::~Layer()
status_t Layer::setToken(const sp<UserClient>& userClient,
SharedClient* sharedClient, int32_t token)
{
- SharedBufferServer* lcblk = new SharedBufferServer(
+ sp<SharedBufferServer> lcblk = new SharedBufferServer(
sharedClient, token, mBufferManager.getDefaultBufferCount(),
getIdentity());
status_t err = mUserClientRef.setToken(userClient, lcblk, token);
- if (err != NO_ERROR) {
- LOGE("ClientRef::setToken(%p, %p, %u) failed",
- userClient.get(), lcblk, token);
- delete lcblk;
+
+ LOGE_IF(err != NO_ERROR,
+ "ClientRef::setToken(%p, %p, %u) failed",
+ userClient.get(), lcblk.get(), token);
+
+ if (err == NO_ERROR) {
+ // we need to free the buffers associated with this surface
}
return err;
@@ -95,6 +98,11 @@ int32_t Layer::getToken() const
return mUserClientRef.getToken();
}
+sp<UserClient> Layer::getClient() const
+{
+ return mUserClientRef.getClient();
+}
+
// called with SurfaceFlinger::mStateLock as soon as the layer is entered
// in the purgatory list
void Layer::onRemoved()
@@ -626,11 +634,10 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const
// ---------------------------------------------------------------------------
Layer::ClientRef::ClientRef()
- : mToken(-1) {
+ : mControlBlock(0), mToken(-1) {
}
Layer::ClientRef::~ClientRef() {
- delete lcblk;
}
int32_t Layer::ClientRef::getToken() const {
@@ -638,14 +645,25 @@ int32_t Layer::ClientRef::getToken() const {
return mToken;
}
+sp<UserClient> Layer::ClientRef::getClient() const {
+ Mutex::Autolock _l(mLock);
+ return mUserClient.promote();
+}
+
status_t Layer::ClientRef::setToken(const sp<UserClient>& uc,
- SharedBufferServer* sharedClient, int32_t token) {
+ const sp<SharedBufferServer>& sharedClient, int32_t token) {
Mutex::Autolock _l(mLock);
- if (mToken >= 0)
- return INVALID_OPERATION;
+
+ { // scope for strong mUserClient reference
+ sp<UserClient> userClient(mUserClient.promote());
+ if (mUserClient != 0 && mControlBlock != 0) {
+ mControlBlock->setStatus(NO_INIT);
+ }
+ }
+
mUserClient = uc;
mToken = token;
- lcblk = sharedClient;
+ mControlBlock = sharedClient;
return NO_ERROR;
}
@@ -657,12 +675,16 @@ sp<UserClient> Layer::ClientRef::getUserClientUnsafe() const {
// it makes sure the UserClient (and its associated shared memory)
// won't go away while we're accessing it.
Layer::ClientRef::Access::Access(const ClientRef& ref)
- : lcblk(0)
+ : mControlBlock(0)
{
Mutex::Autolock _l(ref.mLock);
mUserClientStrongRef = ref.mUserClient.promote();
if (mUserClientStrongRef != 0)
- lcblk = ref.lcblk;
+ mControlBlock = ref.mControlBlock;
+}
+
+Layer::ClientRef::Access::~Access()
+{
}
// ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h
index d396ecf..dcb27a0 100644
--- a/libs/surfaceflinger/Layer.h
+++ b/libs/surfaceflinger/Layer.h
@@ -60,6 +60,7 @@ public:
// associate a UserClient to this Layer
status_t setToken(const sp<UserClient>& uc, SharedClient* sc, int32_t idx);
int32_t getToken() const;
+ sp<UserClient> getClient() const;
// Set this Layer's buffers size
void setBufferSize(uint32_t w, uint32_t h);
@@ -119,24 +120,26 @@ private:
ClientRef& operator = (const ClientRef& rhs);
mutable Mutex mLock;
// binder thread, page-flip thread
- SharedBufferServer* lcblk;
+ sp<SharedBufferServer> mControlBlock;
wp<UserClient> mUserClient;
int32_t mToken;
public:
ClientRef();
~ClientRef();
int32_t getToken() const;
+ sp<UserClient> getClient() const;
status_t setToken(const sp<UserClient>& uc,
- SharedBufferServer* sharedClient, int32_t token);
+ const sp<SharedBufferServer>& sharedClient, int32_t token);
sp<UserClient> getUserClientUnsafe() const;
class Access {
Access(const Access& rhs);
Access& operator = (const Access& rhs);
sp<UserClient> mUserClientStrongRef;
- SharedBufferServer* lcblk;
+ sp<SharedBufferServer> mControlBlock;
public:
Access(const ClientRef& ref);
- inline SharedBufferServer* get() const { return lcblk; }
+ ~Access();
+ inline SharedBufferServer* get() const { return mControlBlock.get(); }
};
friend class Access;
};
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 0f73774..4dea62f 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -1718,7 +1718,10 @@ void UserClient::detachLayer(const Layer* layer)
{
int32_t name = layer->getToken();
if (name >= 0) {
- android_atomic_and(~(1LU<<name), &mBitmap);
+ int32_t mask = 1LU<<name;
+ if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) {
+ LOGW("token %d wasn't marked as used %08x", name, int(mBitmap));
+ }
}
}
@@ -1732,24 +1735,31 @@ ssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
sp<Layer> layer(mFlinger->getLayer(sur));
if (layer == 0) return name;
- // this layer already has a token, just return it
- // FIXME: we should check that this token is for the same client
+ // if this layer already has a token, just return it
name = layer->getToken();
- if (name >= 0) return name;
+ if ((name >= 0) && (layer->getClient() == this))
+ return name;
name = 0;
do {
int32_t mask = 1LU<<name;
if ((android_atomic_or(mask, &mBitmap) & mask) == 0) {
// we found and locked that name
- layer->setToken(const_cast<UserClient*>(this), ctrlblk, name);
+ status_t err = layer->setToken(
+ const_cast<UserClient*>(this), ctrlblk, name);
+ if (err != NO_ERROR) {
+ // free the name
+ android_atomic_and(~mask, &mBitmap);
+ name = err;
+ }
break;
}
if (++name > 31)
name = NO_MEMORY;
} while(name >= 0);
- //LOGD("getTokenForSurface(%p) => %d", sur->asBinder().get(), name);
+ //LOGD("getTokenForSurface(%p) => %d (client=%p, bitmap=%08lx)",
+ // sur->asBinder().get(), name, this, mBitmap);
return name;
}
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp
index 1dd8642..d67a589 100644
--- a/libs/surfaceflinger_client/SharedBufferStack.cpp
+++ b/libs/surfaceflinger_client/SharedBufferStack.cpp
@@ -494,6 +494,10 @@ SharedBufferServer::SharedBufferServer(SharedClient* sharedClient,
}
}
+SharedBufferServer::~SharedBufferServer()
+{
+}
+
ssize_t SharedBufferServer::retireAndLock()
{
RWLock::AutoRLock _l(mLock);
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 6fe4c4a..8617d94a 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -236,17 +236,15 @@ status_t SurfaceControl::validate() const
status_t SurfaceControl::writeSurfaceToParcel(
const sp<SurfaceControl>& control, Parcel* parcel)
{
- uint32_t flags = 0;
- uint32_t format = 0;
+ sp<ISurface> sur;
uint32_t identity = 0;
uint32_t width = 0;
uint32_t height = 0;
- sp<SurfaceComposerClient> client;
- sp<ISurface> sur;
+ uint32_t format = 0;
+ uint32_t flags = 0;
if (SurfaceControl::isValid(control)) {
- identity = control->mIdentity;
- client = control->mClient;
sur = control->mSurface;
+ identity = control->mIdentity;
width = control->mWidth;
height = control->mHeight;
format = control->mFormat;
@@ -349,6 +347,33 @@ Surface::Surface(const Parcel& parcel, const sp<IBinder>& ref)
init();
}
+status_t Surface::writeToParcel(
+ const sp<Surface>& surface, Parcel* parcel)
+{
+ sp<ISurface> sur;
+ uint32_t identity = 0;
+ uint32_t width = 0;
+ uint32_t height = 0;
+ uint32_t format = 0;
+ uint32_t flags = 0;
+ if (Surface::isValid(surface)) {
+ sur = surface->mSurface;
+ identity = surface->mIdentity;
+ width = surface->mWidth;
+ height = surface->mHeight;
+ format = surface->mFormat;
+ flags = surface->mFlags;
+ }
+ parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
+ parcel->writeInt32(identity);
+ parcel->writeInt32(width);
+ parcel->writeInt32(height);
+ parcel->writeInt32(format);
+ parcel->writeInt32(flags);
+ return NO_ERROR;
+
+}
+
sp<Surface> Surface::readFromParcel(
const Parcel& data, const sp<Surface>& other)
{
@@ -385,11 +410,11 @@ void Surface::init()
mBuffers.insertAt(0, 2);
if (mSurface != 0 && mClient.initCheck() == NO_ERROR) {
- mToken = mClient.getTokenForSurface(mSurface);
- if (mToken >= 0) {
+ int32_t token = mClient.getTokenForSurface(mSurface);
+ if (token >= 0) {
mSharedBufferClient = new SharedBufferClient(
- mClient.getSharedClient(), mToken, 2, mIdentity);
- mInitCheck = mClient.getSharedClient()->validate(mToken);
+ mClient.getSharedClient(), token, 2, mIdentity);
+ mInitCheck = mClient.getSharedClient()->validate(token);
}
}
}
@@ -421,7 +446,7 @@ status_t Surface::validate() const
{
// check that we initialized ourself properly
if (mInitCheck != NO_ERROR) {
- LOGE("invalid token (%d, identity=%u)", mToken, mIdentity);
+ LOGE("invalid token (identity=%u)", mIdentity);
return mInitCheck;
}
@@ -437,17 +462,17 @@ status_t Surface::validate() const
}
if (mIdentity != identity) {
- LOGE("[Surface] using an invalid surface id=%d, "
+ LOGE("[Surface] using an invalid surface, "
"identity=%u should be %d",
- mToken, mIdentity, identity);
+ mIdentity, identity);
return NO_INIT;
}
// check the surface didn't become invalid
status_t err = mSharedBufferClient->getStatus();
if (err != NO_ERROR) {
- LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
- mToken, mIdentity, err, strerror(-err));
+ LOGE("surface (identity=%u) is invalid, err=%d (%s)",
+ mIdentity, err, strerror(-err));
return err;
}
diff --git a/libs/surfaceflinger_client/SurfaceComposerClient.cpp b/libs/surfaceflinger_client/SurfaceComposerClient.cpp
index 5ac0d5d..4096ac6 100644
--- a/libs/surfaceflinger_client/SurfaceComposerClient.cpp
+++ b/libs/surfaceflinger_client/SurfaceComposerClient.cpp
@@ -305,9 +305,7 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface(
sp<ISurface> surface = mClient->createSurface(&data, pid, name,
display, w, h, format, flags);
if (surface != 0) {
- if (uint32_t(data.token) < SharedBufferStack::NUM_LAYERS_MAX) {
- result = new SurfaceControl(this, surface, data, w, h, format, flags);
- }
+ result = new SurfaceControl(this, surface, data, w, h, format, flags);
}
}
return result;
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 3ddde38..4b5f025 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -111,6 +111,9 @@ status_t GraphicBuffer::reallocate(uint32_t w, uint32_t h, PixelFormat f,
if (mOwner != ownData)
return INVALID_OPERATION;
+ if (handle && w==width && h==height && f==format && reqUsage==usage)
+ return NO_ERROR;
+
if (handle) {
GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
allocator.free(handle);
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 8cf2e51..c113ffe 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -317,8 +317,8 @@ android_media_MediaRecorder_prepare(JNIEnv *env, jobject thiz)
jobject surface = env->GetObjectField(thiz, fields.surface);
if (surface != NULL) {
- const sp<Surface>& native_surface = get_surface(env, surface);
- LOGI("prepare: surface=%p (id=%d)", native_surface.get(), native_surface->ID());
+ const sp<Surface> native_surface = get_surface(env, surface);
+ LOGI("prepare: surface=%p (identity=%d)", native_surface.get(), native_surface->getIdentity());
if (process_media_recorder_call(env, mr->setPreviewSurface(native_surface), "java/lang/RuntimeException", "setPreviewSurface failed.")) {
return;
}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 3f5b69d..74d87ba 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -2,21 +2,21 @@
package="com.android.systemui"
android:sharedUserId="android.uid.system">
+ <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
+
<application
android:allowClearUserData="false"
android:label="@string/app_label"
android:icon="@drawable/ic_launcher_settings">
- <receiver
- android:name=".statusbar.StatusBarStarter"
- >
- <intent-filter>
- <action android:name="com.android.internal.policy.statusbar.START" />
- </intent-filter>
- </receiver>
<service
android:name=".statusbar.PhoneStatusBarService"
android:exported="false"
/>
+
+ <activity android:name=".usb.UsbStorageActivity"
+ android:excludeFromRecents="true">
+ </activity>
+
</application>
</manifest>
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_focus.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_focus.9.png
deleted file mode 100644
index 0876bc6..0000000
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_focus.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_normal.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_normal.9.png
deleted file mode 100644
index c01c018..0000000
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_pressed.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_pressed.9.png
deleted file mode 100644
index 343e4ca..0000000
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_focus.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_focus.9.png
deleted file mode 100644
index c3e2415..0000000
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_focus.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_normal.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_normal.9.png
deleted file mode 100644
index b8e399d..0000000
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_pressed.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_pressed.9.png
deleted file mode 100644
index 02b4e9a..0000000
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/layout/status_bar_latest_event.xml b/packages/SystemUI/res/layout/status_bar_latest_event.xml
index 59cc90d..88d9739 100644
--- a/core/res/res/layout/status_bar_latest_event.xml
+++ b/packages/SystemUI/res/layout/status_bar_latest_event.xml
@@ -4,20 +4,20 @@
android:orientation="vertical"
>
- <com.android.server.status.LatestItemView android:id="@+id/content"
+ <com.android.systemui.statusbar.LatestItemView android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="64sp"
- android:background="@drawable/status_bar_item_background"
+ android:background="@android:drawable/status_bar_item_background"
android:focusable="true"
android:clickable="true"
android:paddingRight="6sp"
>
- </com.android.server.status.LatestItemView>
+ </com.android.systemui.statusbar.LatestItemView>
<View
android:layout_width="match_parent"
android:layout_height="1sp"
- android:background="@drawable/divider_horizontal_bright"
+ android:background="@android:drawable/divider_horizontal_bright"
/>
</LinearLayout>
diff --git a/packages/SystemUI/res/values/arrays.xml b/packages/SystemUI/res/values/arrays.xml
deleted file mode 100644
index dbb0e0f..0000000
--- a/packages/SystemUI/res/values/arrays.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/colors.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.
-*/
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
- <!-- Do not translate. Defines the slots for the right-hand side icons. That is to say, the
- icons in the status bar that are not notifications. -->
- <string-array name="status_bar_icon_order">
- <item><xliff:g id="id">TODO: Remove; not used.</xliff:g></item>
- </string-array>
-
-</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
index e9ae69a..a7e5e31 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
@@ -85,13 +85,6 @@ public class PhoneStatusBarService extends StatusBarService {
private static final int MSG_ANIMATE = 1000;
private static final int MSG_ANIMATE_REVEAL = 1001;
- public interface NotificationCallbacks {
- void onSetDisabled(int status);
- void onClearAll();
- void onNotificationClick(String pkg, String tag, int id);
- void onPanelRevealed();
- }
-
private class ExpandedDialog extends Dialog {
ExpandedDialog(Context context) {
super(context, com.android.internal.R.style.Theme_Light_NoTitleBar);
@@ -123,7 +116,6 @@ public class PhoneStatusBarService extends StatusBarService {
Object mQueueLock = new Object();
// icons
- String[] mRightIconSlots;
LinearLayout mIcons;
IconMerger mNotificationIcons;
LinearLayout mStatusIcons;
@@ -160,6 +152,7 @@ public class PhoneStatusBarService extends StatusBarService {
TrackingView mTrackingView;
WindowManager.LayoutParams mTrackingParams;
int mTrackingPosition; // the position of the top of the tracking view.
+ private boolean mPanelSlightlyVisible;
// ticker
private Ticker mTicker;
@@ -208,7 +201,6 @@ public class PhoneStatusBarService extends StatusBarService {
// ================================================================================
private void makeStatusBarView(Context context) {
Resources res = context.getResources();
- mRightIconSlots = res.getStringArray(R.array.status_bar_icon_order);
mHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
mIconWidth = mHeight;
@@ -349,6 +341,16 @@ public class PhoneStatusBarService extends StatusBarService {
final RemoteViews contentView = notification.notification.contentView;
+ if (false) {
+ Slog.d(TAG, "old notification: when=" + oldNotification.notification.when
+ + " ongoing=" + oldNotification.isOngoing()
+ + " expanded=" + oldEntry.expanded
+ + " contentView=" + oldContentView);
+ 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.
if (notification.notification.when == oldNotification.notification.when
@@ -370,6 +372,14 @@ public class PhoneStatusBarService extends StatusBarService {
oldEntry.content.setOnClickListener(new Launcher(contentIntent,
notification.pkg, notification.tag, notification.id));
}
+ // Update the icon.
+ final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
+ notification.notification.icon, notification.notification.iconLevel,
+ notification.notification.number);
+ 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.
@@ -377,9 +387,6 @@ public class PhoneStatusBarService extends StatusBarService {
removeNotificationViews(key);
addNotificationViews(key, notification);
}
- // Update the icon.
- oldEntry.icon.set(new StatusBarIcon(notification.pkg, notification.notification.icon,
- notification.notification.iconLevel, notification.notification.number));
} else {
Slog.d(TAG, "not reusing notification");
removeNotificationViews(key);
@@ -426,11 +433,10 @@ public class PhoneStatusBarService extends StatusBarService {
// create the row view
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View row = inflater.inflate(com.android.internal.R.layout.status_bar_latest_event,
- parent, false);
+ View row = inflater.inflate(R.layout.status_bar_latest_event, parent, false);
// bind the click event to the content area
- ViewGroup content = (ViewGroup)row.findViewById(com.android.internal.R.id.content);
+ ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
content.setOnFocusChangeListener(mFocusChangeListener);
PendingIntent contentIntent = n.contentIntent;
@@ -448,8 +454,9 @@ public class PhoneStatusBarService extends StatusBarService {
exception = e;
}
if (expanded == null) {
- Slog.e(TAG, "couldn't inflate view for package " + notification.pkg, exception);
- row.setVisibility(View.GONE);
+ String ident = notification.pkg + "/0x" + Integer.toHexString(notification.id);
+ Slog.e(TAG, "couldn't inflate view for notification " + ident);
+ return null;
} else {
content.addView(expanded);
row.setDrawingCacheEnabled(true);
@@ -471,14 +478,23 @@ public class PhoneStatusBarService extends StatusBarService {
}
// Construct the expanded view.
final View[] views = makeNotificationView(notification, parent);
+ if (views == null) {
+ handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "
+ + notification);
+ return;
+ }
final View row = views[0];
final View content = views[1];
final View expanded = views[2];
// Construct the icon.
- StatusBarIconView iconView = new StatusBarIconView(this,
+ final StatusBarIconView iconView = new StatusBarIconView(this,
notification.pkg + "/0x" + Integer.toHexString(notification.id));
- iconView.set(new StatusBarIcon(notification.pkg, notification.notification.icon,
- notification.notification.iconLevel, notification.notification.number));
+ final StatusBarIcon ic = new StatusBarIcon(notification.pkg, notification.notification.icon,
+ notification.notification.iconLevel, notification.notification.number);
+ if (!iconView.set(ic)) {
+ handleNotificationError(key, notification, "Coulding create icon: " + ic);
+ return;
+ }
// Add the expanded view.
final int viewIndex = list.add(key, notification, row, content, expanded, iconView);
parent.addView(row, viewIndex);
@@ -964,6 +980,21 @@ public class PhoneStatusBarService extends StatusBarService {
}
}
+ /**
+ * 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, message);
+ } catch (RemoteException ex) {
+ // The end is nigh.
+ }
+ }
+
private class MyTicker extends Ticker {
MyTicker(Context context, StatusBarView sb) {
super(context, sb);
@@ -1265,8 +1296,15 @@ public class PhoneStatusBarService extends StatusBarService {
// because the window itself extends below the content view.
mExpandedParams.y = -disph;
}
- visibilityChanged(visible);
mExpandedDialog.getWindow().setAttributes(mExpandedParams);
+
+ // As long as this isn't just a repositioning that's not supposed to affect
+ // the user's perception of what's showing, call to say that the visibility
+ // has changed. (Otherwise, someone else will call to do that).
+ if (expandedPosition != EXPANDED_LEAVE_ALONE) {
+ Slog.d(TAG, "updateExpandedViewPos visibilityChanged(" + visible + ")");
+ visibilityChanged(visible);
+ }
}
if (SPEW) {
@@ -1296,12 +1334,11 @@ public class PhoneStatusBarService extends StatusBarService {
* turned off. If any other notifications happen, the lights will turn back on. Steve says
* this is what he wants. (see bug 1131461)
*/
- private boolean mPanelSlightlyVisible;
void visibilityChanged(boolean visible) {
if (mPanelSlightlyVisible != visible) {
mPanelSlightlyVisible = visible;
try {
- mBarService.visibilityChanged(visible);
+ mBarService.onPanelRevealed();
} catch (RemoteException ex) {
// Won't fail unless the world has ended.
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 5eb0d68..bc1e798 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -32,7 +32,6 @@ public class StatusBarIconView extends AnimatedImageView {
private StatusBarIcon mIcon;
@ViewDebug.ExportedProperty private String mSlot;
- @ViewDebug.ExportedProperty private boolean mError;
public StatusBarIconView(Context context, String slot) {
super(context);
@@ -52,39 +51,33 @@ public class StatusBarIconView extends AnimatedImageView {
return a.equals(b);
}
- public void set(StatusBarIcon icon) {
- error: {
- final boolean iconEquals = !mError
- && mIcon != null
- && streq(mIcon.iconPackage, icon.iconPackage)
- && mIcon.iconId == icon.iconId;
- final boolean levelEquals = !mError
- && iconEquals
- && mIcon.iconLevel == icon.iconLevel;
- final boolean visibilityEquals = !mError
- && mIcon != null
- && mIcon.visible == icon.visible;
- mError = false;
- if (!iconEquals) {
- Drawable drawable = getIcon(icon);
- if (drawable == null) {
- mError = true;
- Slog.w(PhoneStatusBarService.TAG, "No icon ID for slot " + mSlot);
- break error;
- }
- setImageDrawable(drawable);
- }
- if (!levelEquals) {
- setImageLevel(icon.iconLevel);
- }
- if (!visibilityEquals) {
- setVisibility(icon.visible ? VISIBLE : GONE);
+ /**
+ * Returns whether the set succeeded.
+ */
+ public boolean set(StatusBarIcon icon) {
+ final boolean iconEquals = mIcon != null
+ && streq(mIcon.iconPackage, icon.iconPackage)
+ && mIcon.iconId == icon.iconId;
+ final boolean levelEquals = iconEquals
+ && mIcon.iconLevel == icon.iconLevel;
+ final boolean visibilityEquals = mIcon != null
+ && mIcon.visible == icon.visible;
+ if (!iconEquals) {
+ Drawable drawable = getIcon(icon);
+ if (drawable == null) {
+ Slog.w(PhoneStatusBarService.TAG, "No icon for slot " + mSlot);
+ return false;
}
- mIcon = icon.clone();
+ setImageDrawable(drawable);
+ }
+ if (!levelEquals) {
+ setImageLevel(icon.iconLevel);
}
- if (mError) {
- setVisibility(GONE);
+ if (!visibilityEquals) {
+ setVisibility(icon.visible ? VISIBLE : GONE);
}
+ mIcon = icon.clone();
+ return true;
}
private Drawable getIcon(StatusBarIcon icon) {
@@ -106,7 +99,7 @@ public class StatusBarIconView extends AnimatedImageView {
try {
r = context.getPackageManager().getResourcesForApplication(icon.iconPackage);
} catch (PackageManager.NameNotFoundException ex) {
- Slog.e(PhoneStatusBarService.TAG, "Icon package not found: "+icon.iconPackage, ex);
+ Slog.e(PhoneStatusBarService.TAG, "Icon package not found: " + icon.iconPackage);
return null;
}
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java
index 9ef9d0d..4f39ee4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java
@@ -365,7 +365,7 @@ public class StatusBarPolicy {
// storage
mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
mStorageManager.registerListener(
- new com.android.server.status.StorageNotification(context));
+ new com.android.systemui.usb.StorageNotification(context));
// battery
mService.setIcon("battery", com.android.internal.R.drawable.stat_sys_battery_unknown, 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
index 4d9e695..d200886 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
@@ -48,12 +48,6 @@ public abstract class StatusBarService extends Service implements CommandQueue.C
CommandQueue mCommandQueue;
IStatusBarService mBarService;
- /* TODO
- H mHandler = new H();
- Object mQueueLock = new Object();
- NotificationCallbacks mNotificationCallbacks;
- */
-
@Override
public void onCreate() {
// Connect in to the status bar manager service
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStarter.java
deleted file mode 100644
index 2b9dfb0..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStarter.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.BroadcastReceiver;
-import android.util.Log;
-
-/**
- * Receive a broadcast from the StatusBarManagerService at boot time, and
- * kick off the StatusBarService.
- */
-public class StatusBarStarter extends BroadcastReceiver {
- private static final String TAG = "StatusBarStarter";
-
- @Override
- public void onReceive(Context context, Intent intent) {
- Log.d(TAG, "StatusBarStarter onReceive intent=" + intent);
- context.startService(new Intent(context, PhoneStatusBarService.class));
- }
-}
-
-
diff --git a/services/java/com/android/server/status/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 8da8cd3..f8abc5a 100644
--- a/services/java/com/android/server/status/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.status;
+package com.android.systemui.usb;
import android.app.Activity;
import android.app.Notification;
@@ -80,9 +80,10 @@ public class StorageNotification extends StorageEventListener {
mContext = context;
mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
- mUmsAvailable = mStorageManager.isUsbMassStorageConnected();
+ final boolean connected = mStorageManager.isUsbMassStorageConnected();
Slog.d(TAG, String.format( "Startup with UMS connection %s (media state %s)", mUmsAvailable,
Environment.getExternalStorageState()));
+ onUsbMassStorageConnectionChanged(connected);
}
/*
@@ -122,7 +123,7 @@ public class StorageNotification extends StorageEventListener {
* for stopping UMS.
*/
Intent intent = new Intent();
- intent.setClass(mContext, com.android.server.status.UsbStorageActivity.class);
+ intent.setClass(mContext, com.android.systemui.usb.UsbStorageActivity.class);
PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
setUsbStorageNotification(
com.android.internal.R.string.usb_storage_stop_notification_title,
@@ -240,7 +241,7 @@ public class StorageNotification extends StorageEventListener {
if (available) {
Intent intent = new Intent();
- intent.setClass(mContext, com.android.server.status.UsbStorageActivity.class);
+ intent.setClass(mContext, com.android.systemui.usb.UsbStorageActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
final boolean adbOn = 1 == Settings.Secure.getInt(
diff --git a/services/java/com/android/server/status/UsbStorageActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java
index e8631c5..55d31ec 100644
--- a/services/java/com/android/server/status/UsbStorageActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.status;
+package com.android.systemui.usb;
import com.android.internal.R;
import android.app.Activity;
diff --git a/policy/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/com/android/internal/policy/impl/PhoneWindowManager.java
index 73a57ee..d152bc4 100755
--- a/policy/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -957,12 +957,20 @@ public class PhoneWindowManager implements WindowManagerPolicy {
public int prepareAddWindowLw(WindowState win, WindowManager.LayoutParams attrs) {
switch (attrs.type) {
case TYPE_STATUS_BAR:
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.STATUS_BAR_SERVICE,
+ "PhoneWindowManager");
+ // TODO: Need to handle the race condition of the status bar proc
+ // dying and coming back before the removeWindowLw cleanup has happened.
if (mStatusBar != null) {
return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
}
mStatusBar = win;
break;
case TYPE_STATUS_BAR_PANEL:
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.STATUS_BAR_SERVICE,
+ "PhoneWindowManager");
mStatusBarPanels.add(win);
break;
case TYPE_KEYGUARD:
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index 7fb7db0..19d146d 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -367,6 +367,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
out.endDocument();
stream.close();
journal.commit();
+ sendChangedNotification();
} catch (IOException e) {
try {
if (stream != null) {
@@ -379,6 +380,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
+ private void sendChangedNotification() {
+ Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
+ intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ mContext.sendBroadcast(intent);
+ }
+
private void loadSettingsLocked() {
JournaledFile journal = makeJournaledFile();
FileInputStream stream = null;
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index a1f26f2..4d35bec 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -26,7 +26,7 @@ import com.android.internal.view.IInputMethodManager;
import com.android.internal.view.IInputMethodSession;
import com.android.internal.view.InputBindResult;
-import com.android.server.status.StatusBarManagerService;
+import com.android.server.StatusBarManagerService;
import org.xmlpull.v1.XmlPullParserException;
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index ac3b23b..6f44e8e 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -17,7 +17,7 @@
package com.android.server;
import com.android.internal.statusbar.StatusBarNotification;
-import com.android.server.status.StatusBarManagerService;
+import com.android.server.StatusBarManagerService;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
@@ -70,6 +70,8 @@ class NotificationManagerService extends INotificationManager.Stub
private static final String TAG = "NotificationService";
private static final boolean DBG = false;
+ private static final int MAX_PACKAGE_NOTIFICATIONS = 50;
+
// message codes
private static final int MESSAGE_TIMEOUT = 2;
@@ -301,6 +303,12 @@ class NotificationManagerService extends INotificationManager.Stub
updateLightsLocked();
}
}
+
+ public void onNotificationError(String pkg, String tag, int id, String message) {
+ Slog.d(TAG, "onNotification error pkg=" + pkg + " tag=" + tag + " id=" + id);
+ cancelNotification(pkg, tag, id, 0, 0);
+ // TODO: Tell the activity manager.
+ }
};
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@@ -657,6 +665,26 @@ class NotificationManagerService extends INotificationManager.Stub
{
checkIncomingCall(pkg);
+ // Limit the number of notifications that any given package except the android
+ // package can enqueue. Prevents DOS attacks and deals with leaks.
+ if (!"android".equals(pkg)) {
+ synchronized (mNotificationList) {
+ int count = 0;
+ final int N = mNotificationList.size();
+ for (int i=0; i<N; i++) {
+ final NotificationRecord r = mNotificationList.get(i);
+ if (r.pkg.equals(pkg)) {
+ count++;
+ if (count >= MAX_PACKAGE_NOTIFICATIONS) {
+ Slog.e(TAG, "Package has already posted " + count
+ + " notifications. Not showing more. package=" + pkg);
+ return;
+ }
+ }
+ }
+ }
+ }
+
// This conditional is a dirty hack to limit the logging done on
// behalf of the download manager without affecting other apps.
if (!pkg.equals("com.android.providers.downloads")
diff --git a/services/java/com/android/server/status/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java
index 0af1ebb..1a16387 100644
--- a/services/java/com/android/server/status/StatusBarManagerService.java
+++ b/services/java/com/android/server/StatusBarManagerService.java
@@ -14,11 +14,12 @@
* limitations under the License.
*/
-package com.android.server.status;
+package com.android.server;
import android.app.PendingIntent;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -55,9 +56,6 @@ public class StatusBarManagerService extends IStatusBarService.Stub
static final String TAG = "StatusBarManagerService";
static final boolean SPEW = true;
- public static final String ACTION_STATUSBAR_START
- = "com.android.internal.policy.statusbar.START";
-
final Context mContext;
Handler mHandler = new Handler();
NotificationCallbacks mNotificationCallbacks;
@@ -87,6 +85,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub
void onClearAll();
void onNotificationClick(String pkg, String tag, int id);
void onPanelRevealed();
+ void onNotificationError(String pkg, String tag, int id, String message);
}
/**
@@ -96,7 +95,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub
mContext = context;
final Resources res = context.getResources();
- mIcons.defineSlots(res.getStringArray(com.android.internal.R.array.status_bar_icon_order));
+ mIcons.defineSlots(res.getStringArray(com.android.internal.R.array.config_statusBarIcons));
}
public void setNotificationCallbacks(NotificationCallbacks listener) {
@@ -111,9 +110,12 @@ public class StatusBarManagerService extends IStatusBarService.Stub
}
public void systemReady2() {
- // Start the status bar app
- Intent intent = new Intent(ACTION_STATUSBAR_START);
- mContext.sendBroadcast(intent /** permission **/);
+ ComponentName cn = ComponentName.unflattenFromString(
+ mContext.getString(com.android.internal.R.string.config_statusBarComponent));
+ Intent intent = new Intent();
+ intent.setComponent(cn);
+ Slog.i(TAG, "Starting service: " + cn);
+ mContext.startService(intent);
}
// ================================================================================
@@ -248,12 +250,19 @@ public class StatusBarManagerService extends IStatusBarService.Stub
"StatusBarManagerService");
}
+ private void enforceStatusBarService() {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE,
+ "StatusBarManagerService");
+ }
+
// ================================================================================
// Callbacks from the status bar service.
// ================================================================================
public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList,
List<IBinder> notificationKeys, List<StatusBarNotification> notifications) {
+ enforceStatusBarService();
+
Slog.i(TAG, "registerStatusBar bar=" + bar);
mBar = bar;
synchronized (mIcons) {
@@ -268,18 +277,32 @@ public class StatusBarManagerService extends IStatusBarService.Stub
}
/**
- * The status bar service should call this when the user changes whether
- * the status bar is visible or not.
+ * The status bar service should call this each time the user brings the panel from
+ * invisible to visible in order to clear the notification light.
*/
- public void visibilityChanged(boolean visible) {
- //Slog.d(TAG, "visibilityChanged visible=" + visible);
+ public void onPanelRevealed() {
+ enforceStatusBarService();
+
+ // tell the notification manager to turn off the lights.
+ mNotificationCallbacks.onPanelRevealed();
}
public void onNotificationClick(String pkg, String tag, int id) {
+ enforceStatusBarService();
+
mNotificationCallbacks.onNotificationClick(pkg, tag, id);
}
+ public void onNotificationError(String pkg, String tag, int id, String message) {
+ enforceStatusBarService();
+
+ // WARNING: this will call back into us to do the remove. Don't hold any locks.
+ mNotificationCallbacks.onNotificationError(pkg, tag, id, message);
+ }
+
public void onClearAllNotifications() {
+ enforceStatusBarService();
+
mNotificationCallbacks.onClearAll();
}
@@ -423,24 +446,6 @@ public class StatusBarManagerService extends IStatusBarService.Stub
}
}
- /**
- * The LEDs are turned o)ff when the notification panel is shown, even just a little bit.
- * This was added last-minute and is inconsistent with the way the rest of the notifications
- * are handled, because the notification isn't really cancelled. The lights are just
- * turned off. If any other notifications happen, the lights will turn back on. Steve says
- * this is what he wants. (see bug 1131461)
- */
- private boolean mPanelSlightlyVisible;
- void panelSlightlyVisible(boolean visible) {
- if (mPanelSlightlyVisible != visible) {
- mPanelSlightlyVisible = visible;
- if (visible) {
- // tell the notification manager to turn off the lights.
- mNotificationCallbacks.onPanelRevealed();
- }
- }
- }
-
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 4307cdc..b91bf73 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -17,7 +17,6 @@
package com.android.server;
import com.android.server.am.ActivityManagerService;
-import com.android.server.status.StatusBarManagerService;
import com.android.internal.os.BinderInternal;
import com.android.internal.os.SamplingProfilerIntegration;
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index dcee6e7..ac5e3f1 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -55,7 +55,10 @@ import android.Manifest;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.CompatibilityInfo;
@@ -235,11 +238,20 @@ public class WindowManagerService extends IWindowManager.Stub
*/
private boolean mKeyguardDisabled = false;
+ private static final int ALLOW_DISABLE_YES = 1;
+ private static final int ALLOW_DISABLE_NO = 0;
+ private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
+ private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
+
final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
public void acquired() {
- mPolicy.enableKeyguard(false);
- mKeyguardDisabled = true;
+ if (shouldAllowDisableKeyguard()) {
+ mPolicy.enableKeyguard(false);
+ mKeyguardDisabled = true;
+ } else {
+ Log.v(TAG, "Not disabling keyguard since device policy is enforced");
+ }
}
public void released() {
mPolicy.enableKeyguard(true);
@@ -250,6 +262,18 @@ public class WindowManagerService extends IWindowManager.Stub
}
};
+ final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mPolicy.enableKeyguard(true);
+ synchronized(mKeyguardTokenWatcher) {
+ // lazily evaluate this next time we're asked to disable keyguard
+ mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
+ mKeyguardDisabled = false;
+ }
+ }
+ };
+
final Context mContext;
final boolean mHaveInputMethods;
@@ -610,6 +634,11 @@ public class WindowManagerService extends IWindowManager.Stub
mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
+ // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
+ mContext.registerReceiver(mBroadcastReceiver, filter);
+
int max_events_per_sec = 35;
try {
max_events_per_sec = Integer.parseInt(SystemProperties
@@ -4173,17 +4202,20 @@ public class WindowManagerService extends IWindowManager.Stub
// Misc IWindowSession methods
// -------------------------------------------------------------
- private boolean allowDisableKeyguard()
+ private boolean shouldAllowDisableKeyguard()
{
- // We fail safe if this gets called before the service has started.
- boolean allow = false;
- DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
- Context.DEVICE_POLICY_SERVICE);
- if (dpm != null) {
- allow = dpm.getPasswordQuality(null)
- == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+ // We fail safe and prevent disabling keyguard in the unlikely event this gets
+ // called before DevicePolicyManagerService has started.
+ if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
+ DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
+ Context.DEVICE_POLICY_SERVICE);
+ if (dpm != null) {
+ mAllowDisableKeyguard = dpm.getPasswordQuality(null)
+ == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
+ ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
+ }
}
- return allow;
+ return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
}
public void disableKeyguard(IBinder token, String tag) {
@@ -4192,12 +4224,8 @@ public class WindowManagerService extends IWindowManager.Stub
throw new SecurityException("Requires DISABLE_KEYGUARD permission");
}
- if (allowDisableKeyguard()) {
- synchronized (mKeyguardTokenWatcher) {
- mKeyguardTokenWatcher.acquire(token, tag);
- }
- } else {
- Log.w(TAG, tag + ": disableKeyguard() ignored while DevicePolicyAmin is enabled.");
+ synchronized (mKeyguardTokenWatcher) {
+ mKeyguardTokenWatcher.acquire(token, tag);
}
}
@@ -4207,29 +4235,25 @@ public class WindowManagerService extends IWindowManager.Stub
throw new SecurityException("Requires DISABLE_KEYGUARD permission");
}
- if (allowDisableKeyguard()) {
- synchronized (mKeyguardTokenWatcher) {
- mKeyguardTokenWatcher.release(token);
-
- if (!mKeyguardTokenWatcher.isAcquired()) {
- // If we are the last one to reenable the keyguard wait until
- // we have actaully finished reenabling until returning.
- // It is possible that reenableKeyguard() can be called before
- // the previous disableKeyguard() is handled, in which case
- // neither mKeyguardTokenWatcher.acquired() or released() would
- // be called. In that case mKeyguardDisabled will be false here
- // and we have nothing to wait for.
- while (mKeyguardDisabled) {
- try {
- mKeyguardTokenWatcher.wait();
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
+ synchronized (mKeyguardTokenWatcher) {
+ mKeyguardTokenWatcher.release(token);
+
+ if (!mKeyguardTokenWatcher.isAcquired()) {
+ // If we are the last one to reenable the keyguard wait until
+ // we have actually finished reenabling until returning.
+ // It is possible that reenableKeyguard() can be called before
+ // the previous disableKeyguard() is handled, in which case
+ // neither mKeyguardTokenWatcher.acquired() or released() would
+ // be called. In that case mKeyguardDisabled will be false here
+ // and we have nothing to wait for.
+ while (mKeyguardDisabled) {
+ try {
+ mKeyguardTokenWatcher.wait();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
}
}
}
- } else {
- Log.w(TAG, "reenableKeyguard() ignored while DevicePolicyAmin is enabled.");
}
}
diff --git a/services/java/com/android/server/status/LatestItemView.java b/services/java/com/android/server/status/LatestItemView.java
deleted file mode 100644
index fe8d164..0000000
--- a/services/java/com/android/server/status/LatestItemView.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2008 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.server.status;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.MotionEvent;
-import android.widget.FrameLayout;
-
-public class LatestItemView extends FrameLayout {
-
- public LatestItemView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public boolean dispatchTouchEvent(MotionEvent ev) {
- return onTouchEvent(ev);
- }
-}
diff --git a/services/java/com/android/server/status/package.html b/services/java/com/android/server/status/package.html
deleted file mode 100755
index c9f96a6..0000000
--- a/services/java/com/android/server/status/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-
-{@hide}
-
-</body>
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 3602fec..4d071e3 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -44,6 +44,7 @@ public class NotificationTestList extends TestActivity
Vibrator mVibrator = new Vibrator();
Handler mHandler = new Handler();
+ long mActivityCreateTime = System.currentTimeMillis();
long mChronometerBase = 0;
@Override
@@ -122,29 +123,49 @@ public class NotificationTestList extends TestActivity
}
},
- new Test("Bad Icon") {
+ new Test("Bad Icon #1 (when=create)") {
public void run() {
- mNM.notify(1, new Notification(NotificationTestList.this,
- R.layout.chrono_notification, /* not a drawable! */
- null, System.currentTimeMillis()-(1000*60*60*24),
- "(453) 123-2328",
- "", null));
+ Notification n = new Notification(R.layout.chrono_notification /* not an icon */,
+ null, mActivityCreateTime);
+ n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
+ "This is the same notification!!!", makeIntent());
+ mNM.notify(1, n);
}
},
- new Test("Bad resource #2") {
- public void run()
- {
- Notification n = new Notification(NotificationTestList.this,
- R.drawable.ic_statusbar_missedcall,
- null, System.currentTimeMillis()-(1000*60*60*24),
- "(453) 123-2328",
- "", null);
+ new Test("Bad Icon #1 (when=now)") {
+ public void run() {
+ Notification n = new Notification(R.layout.chrono_notification /* not an icon */,
+ null, System.currentTimeMillis());
+ n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
+ "This is the same notification!!!", makeIntent());
+ mNM.notify(1, n);
+ }
+ },
+
+ new Test("Bad resource #1 (when=create)") {
+ public void run() {
+ Notification n = new Notification(R.drawable.icon2,
+ null, mActivityCreateTime);
+ n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
+ "This is the same notification!!!", makeIntent());
n.contentView.setInt(1 /*bogus*/, "bogus method", 666);
- mNM.notify(2, n);
+ mNM.notify(1, n);
}
},
+ new Test("Bad resource #1 (when=now)") {
+ public void run() {
+ Notification n = new Notification(R.drawable.icon2,
+ null, System.currentTimeMillis());
+ n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
+ "This is the same notification!!!", makeIntent());
+ n.contentView.setInt(1 /*bogus*/, "bogus method", 666);
+ mNM.notify(1, n);
+ }
+ },
+
+
new Test("Bad resource #3") {
public void run()
{
@@ -421,7 +442,7 @@ public class NotificationTestList extends TestActivity
new Test("Persistent #1") {
public void run() {
Notification n = new Notification(R.drawable.icon1, "tick tick tick",
- System.currentTimeMillis());
+ mActivityCreateTime);
n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
"This is a notification!!!", makeIntent());
mNM.notify(1, n);
@@ -481,6 +502,16 @@ public class NotificationTestList extends TestActivity
}
},
+ new Test("Persistent #1 - different icon") {
+ public void run() {
+ Notification n = new Notification(R.drawable.icon2, null,
+ mActivityCreateTime);
+ n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
+ "This is the same notification!!!", makeIntent());
+ mNM.notify(1, n);
+ }
+ },
+
new Test("Chronometer Start") {
public void run() {
Notification n = new Notification(R.drawable.icon2, "me me me me",
diff --git a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
index 3532e30..cb94e52 100644
--- a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
@@ -157,5 +157,22 @@ public class StatusBarTest extends TestActivity
}, 3000);
}
},
+ new Test("More icons") {
+ public void run() {
+ for (String slot: new String[] {
+ "sync_failing",
+ "gps",
+ "bluetooth",
+ "tty",
+ "speakerphone",
+ "mute",
+ "wifi",
+ "alarm_clock",
+ "secure",
+ }) {
+ mStatusBarManager.setIconVisibility(slot, true);
+ }
+ }
+ },
};
}