Merge "Tweaks to Activity up navigation"
diff --git a/api/current.txt b/api/current.txt
index e6a01a8..3e177ad 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -16688,6 +16688,7 @@
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/phone_v2";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/phone_v2";
field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String NORMALIZED_NUMBER = "data4";
field public static final java.lang.String NUMBER = "data1";
field public static final int TYPE_ASSISTANT = 19; // 0x13
field public static final int TYPE_CALLBACK = 8; // 0x8
@@ -17048,6 +17049,7 @@
protected static abstract interface ContactsContract.PhoneLookupColumns {
field public static final java.lang.String LABEL = "label";
+ field public static final java.lang.String NORMALIZED_NUMBER = "normalized_number";
field public static final java.lang.String NUMBER = "number";
field public static final java.lang.String TYPE = "type";
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 736dd24..18d682d 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2000,8 +2000,8 @@
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_USB_ANLG_HEADSET_PLUG =
- "android.intent.action.USB_ANLG_HEADSET_PLUG";
+ public static final String ACTION_ANALOG_AUDIO_DOCK_PLUG =
+ "android.intent.action.ANALOG_AUDIO_DOCK_PLUG";
/**
* Broadcast Action: A digital audio speaker/headset plugged in or unplugged.
@@ -2015,8 +2015,8 @@
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_USB_DGTL_HEADSET_PLUG =
- "android.intent.action.USB_DGTL_HEADSET_PLUG";
+ public static final String ACTION_DIGITAL_AUDIO_DOCK_PLUG =
+ "android.intent.action.DIGITAL_AUDIO_DOCK_PLUG";
/**
* Broadcast Action: A HMDI cable was plugged or unplugged
@@ -2034,22 +2034,6 @@
"android.intent.action.HDMI_AUDIO_PLUG";
/**
- * Broadcast Action: A USB audio device was plugged in or unplugged.
- *
- * <p>The intent will have the following extra values:
- * <ul>
- * <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
- * <li><em>card</em> - ALSA card number (integer) </li>
- * <li><em>device</em> - ALSA device number (integer) </li>
- * </ul>
- * </ul>
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_USB_AUDIO_DEVICE_PLUG =
- "android.intent.action.USB_AUDIO_DEVICE_PLUG";
-
- /**
* Broadcast Action: A USB audio accessory was plugged in or unplugged.
*
* <p>The intent will have the following extra values:
@@ -2066,6 +2050,22 @@
"android.intent.action.USB_AUDIO_ACCESSORY_PLUG";
/**
+ * Broadcast Action: A USB audio device was plugged in or unplugged.
+ *
+ * <p>The intent will have the following extra values:
+ * <ul>
+ * <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
+ * <li><em>card</em> - ALSA card number (integer) </li>
+ * <li><em>device</em> - ALSA device number (integer) </li>
+ * </ul>
+ * </ul>
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_USB_AUDIO_DEVICE_PLUG =
+ "android.intent.action.USB_AUDIO_DEVICE_PLUG";
+
+ /**
* <p>Broadcast Action: The user has switched on advanced settings in the settings app:</p>
* <ul>
* <li><em>state</em> - A boolean value indicating whether the settings is on or off.</li>
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 7a1ef66..c58725d 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -352,10 +352,9 @@
* on matching {@link #uid} and {@link #tag} rows. Ignores {@link #iface},
* since operation counts are at data layer.
*/
- @Deprecated
public void spliceOperationsFrom(NetworkStats stats) {
for (int i = 0; i < size; i++) {
- final int j = stats.findIndex(IFACE_ALL, uid[i], set[i], tag[i]);
+ final int j = stats.findIndex(iface[i], uid[i], set[i], tag[i]);
if (j == -1) {
operations[i] = 0;
} else {
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index d724d56..0e9306b 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -4531,8 +4531,6 @@
/**
* The phone number's E164 representation.
* <P>Type: TEXT</P>
- *
- * @hide
*/
public static final String NORMALIZED_NUMBER = "normalized_number";
}
@@ -5408,10 +5406,10 @@
public static final String NUMBER = DATA;
/**
- * The phone number's E164 representation.
+ * The phone number's E164 representation. This value can be omitted in which
+ * case the provider will try to automatically infer it. If present, {@link #NUMBER}
+ * has to be set as well (it will be ignored otherwise).
* <P>Type: TEXT</P>
- *
- * @hide
*/
public static final String NORMALIZED_NUMBER = DATA4;
diff --git a/core/java/android/widget/Chronometer.java b/core/java/android/widget/Chronometer.java
index 9c9eb4b..b7a126e 100644
--- a/core/java/android/widget/Chronometer.java
+++ b/core/java/android/widget/Chronometer.java
@@ -248,7 +248,6 @@
}
}
setText(text);
- Slog.v("Chronometer", "updateText: sec=" + seconds + " mFormat=" + mFormat + " text=" + text);
}
private void updateRunning() {
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 655a834..19bc154 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -416,8 +416,8 @@
if (env != NULL && clazz != NULL) {
env->DeleteGlobalRef(clazz);
}
- if (looper != NULL && mainWorkRead >= 0) {
- looper->removeFd(mainWorkRead);
+ if (messageQueue != NULL && mainWorkRead >= 0) {
+ messageQueue->getLooper()->removeFd(mainWorkRead);
}
if (nativeInputQueue != NULL) {
nativeInputQueue->mWorkWrite = -1;
@@ -481,7 +481,7 @@
// These are used to wake up the main thread to process work.
int mainWorkRead;
int mainWorkWrite;
- sp<Looper> looper;
+ sp<MessageQueue> messageQueue;
};
void android_NativeActivity_finish(ANativeActivity* activity) {
@@ -515,16 +515,6 @@
// ------------------------------------------------------------------------
-static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
- if (env->ExceptionCheck()) {
- ALOGE("An exception was thrown by callback '%s'.", methodName);
- LOGE_EX(env);
- env->ExceptionClear();
- return true;
- }
- return false;
-}
-
/*
* Callback for handling native events on the application's main thread.
*/
@@ -551,7 +541,8 @@
if (inputEventObj) {
handled = code->env->CallBooleanMethod(code->clazz,
gNativeActivityClassInfo.dispatchUnhandledKeyEvent, inputEventObj);
- checkAndClearExceptionFromCallback(code->env, "dispatchUnhandledKeyEvent");
+ code->messageQueue->raiseAndClearException(
+ code->env, "dispatchUnhandledKeyEvent");
code->env->DeleteLocalRef(inputEventObj);
} else {
ALOGE("Failed to obtain key event for dispatchUnhandledKeyEvent.");
@@ -566,7 +557,7 @@
if (inputEventObj) {
code->env->CallVoidMethod(code->clazz,
gNativeActivityClassInfo.preDispatchKeyEvent, inputEventObj, seq);
- checkAndClearExceptionFromCallback(code->env, "preDispatchKeyEvent");
+ code->messageQueue->raiseAndClearException(code->env, "preDispatchKeyEvent");
code->env->DeleteLocalRef(inputEventObj);
} else {
ALOGE("Failed to obtain key event for preDispatchKeyEvent.");
@@ -575,27 +566,27 @@
} break;
case CMD_FINISH: {
code->env->CallVoidMethod(code->clazz, gNativeActivityClassInfo.finish);
- checkAndClearExceptionFromCallback(code->env, "finish");
+ code->messageQueue->raiseAndClearException(code->env, "finish");
} break;
case CMD_SET_WINDOW_FORMAT: {
code->env->CallVoidMethod(code->clazz,
gNativeActivityClassInfo.setWindowFormat, work.arg1);
- checkAndClearExceptionFromCallback(code->env, "setWindowFormat");
+ code->messageQueue->raiseAndClearException(code->env, "setWindowFormat");
} break;
case CMD_SET_WINDOW_FLAGS: {
code->env->CallVoidMethod(code->clazz,
gNativeActivityClassInfo.setWindowFlags, work.arg1, work.arg2);
- checkAndClearExceptionFromCallback(code->env, "setWindowFlags");
+ code->messageQueue->raiseAndClearException(code->env, "setWindowFlags");
} break;
case CMD_SHOW_SOFT_INPUT: {
code->env->CallVoidMethod(code->clazz,
gNativeActivityClassInfo.showIme, work.arg1);
- checkAndClearExceptionFromCallback(code->env, "showIme");
+ code->messageQueue->raiseAndClearException(code->env, "showIme");
} break;
case CMD_HIDE_SOFT_INPUT: {
code->env->CallVoidMethod(code->clazz,
gNativeActivityClassInfo.hideIme, work.arg1);
- checkAndClearExceptionFromCallback(code->env, "hideIme");
+ code->messageQueue->raiseAndClearException(code->env, "hideIme");
} break;
default:
ALOGW("Unknown work command: %d", work.cmd);
@@ -634,9 +625,9 @@
return 0;
}
- code->looper = android_os_MessageQueue_getLooper(env, messageQueue);
- if (code->looper == NULL) {
- ALOGW("Unable to retrieve MessageQueue's Looper");
+ code->messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueue);
+ if (code->messageQueue == NULL) {
+ ALOGW("Unable to retrieve native MessageQueue");
delete code;
return 0;
}
@@ -655,7 +646,8 @@
result = fcntl(code->mainWorkWrite, F_SETFL, O_NONBLOCK);
SLOGW_IF(result != 0, "Could not make main work write pipe "
"non-blocking: %s", strerror(errno));
- code->looper->addFd(code->mainWorkRead, 0, ALOOPER_EVENT_INPUT, mainWorkCallback, code);
+ code->messageQueue->getLooper()->addFd(
+ code->mainWorkRead, 0, ALOOPER_EVENT_INPUT, mainWorkCallback, code);
code->ANativeActivity::callbacks = &code->callbacks;
if (env->GetJavaVM(&code->vm) < 0) {
diff --git a/core/jni/android_os_MessageQueue.cpp b/core/jni/android_os_MessageQueue.cpp
index 12a77d5..a4dcac6 100644
--- a/core/jni/android_os_MessageQueue.cpp
+++ b/core/jni/android_os_MessageQueue.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "MessageQueue-JNI"
#include "JNIHelp.h"
+#include <android_runtime/AndroidRuntime.h>
#include <utils/Looper.h>
#include <utils/Log.h>
@@ -24,31 +25,46 @@
namespace android {
-// ----------------------------------------------------------------------------
-
static struct {
jfieldID mPtr; // native object attached to the DVM MessageQueue
} gMessageQueueClassInfo;
-// ----------------------------------------------------------------------------
-class NativeMessageQueue {
+class NativeMessageQueue : public MessageQueue {
public:
NativeMessageQueue();
- ~NativeMessageQueue();
+ virtual ~NativeMessageQueue();
- inline sp<Looper> getLooper() { return mLooper; }
+ virtual void raiseException(JNIEnv* env, const char* msg, jthrowable exceptionObj);
- void pollOnce(int timeoutMillis);
+ void pollOnce(JNIEnv* env, int timeoutMillis);
+
void wake();
private:
- sp<Looper> mLooper;
+ bool mInCallback;
+ jthrowable mExceptionObj;
};
-// ----------------------------------------------------------------------------
-NativeMessageQueue::NativeMessageQueue() {
+MessageQueue::MessageQueue() {
+}
+
+MessageQueue::~MessageQueue() {
+}
+
+bool MessageQueue::raiseAndClearException(JNIEnv* env, const char* msg) {
+ jthrowable exceptionObj = env->ExceptionOccurred();
+ if (exceptionObj) {
+ env->ExceptionClear();
+ raiseException(env, msg, exceptionObj);
+ env->DeleteLocalRef(exceptionObj);
+ return true;
+ }
+ return false;
+}
+
+NativeMessageQueue::NativeMessageQueue() : mInCallback(false), mExceptionObj(NULL) {
mLooper = Looper::getForThread();
if (mLooper == NULL) {
mLooper = new Looper(false);
@@ -59,8 +75,32 @@
NativeMessageQueue::~NativeMessageQueue() {
}
-void NativeMessageQueue::pollOnce(int timeoutMillis) {
+void NativeMessageQueue::raiseException(JNIEnv* env, const char* msg, jthrowable exceptionObj) {
+ if (exceptionObj) {
+ if (mInCallback) {
+ if (mExceptionObj) {
+ env->DeleteLocalRef(mExceptionObj);
+ }
+ mExceptionObj = jthrowable(env->NewLocalRef(exceptionObj));
+ ALOGE("Exception in MessageQueue callback: %s", msg);
+ jniLogException(env, ANDROID_LOG_ERROR, LOG_TAG, exceptionObj);
+ } else {
+ ALOGE("Exception: %s", msg);
+ jniLogException(env, ANDROID_LOG_ERROR, LOG_TAG, exceptionObj);
+ LOG_ALWAYS_FATAL("raiseException() was called when not in a callback, exiting.");
+ }
+ }
+}
+
+void NativeMessageQueue::pollOnce(JNIEnv* env, int timeoutMillis) {
+ mInCallback = true;
mLooper->pollOnce(timeoutMillis);
+ mInCallback = false;
+ if (mExceptionObj) {
+ env->Throw(mExceptionObj);
+ env->DeleteLocalRef(mExceptionObj);
+ mExceptionObj = NULL;
+ }
}
void NativeMessageQueue::wake() {
@@ -81,19 +121,20 @@
reinterpret_cast<jint>(nativeMessageQueue));
}
-sp<Looper> android_os_MessageQueue_getLooper(JNIEnv* env, jobject messageQueueObj) {
+sp<MessageQueue> android_os_MessageQueue_getMessageQueue(JNIEnv* env, jobject messageQueueObj) {
NativeMessageQueue* nativeMessageQueue =
android_os_MessageQueue_getNativeMessageQueue(env, messageQueueObj);
- return nativeMessageQueue != NULL ? nativeMessageQueue->getLooper() : NULL;
+ return nativeMessageQueue;
}
static void android_os_MessageQueue_nativeInit(JNIEnv* env, jobject obj) {
NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();
- if (! nativeMessageQueue) {
+ if (!nativeMessageQueue) {
jniThrowRuntimeException(env, "Unable to allocate native queue");
return;
}
+ nativeMessageQueue->incStrong(env);
android_os_MessageQueue_setNativeMessageQueue(env, obj, nativeMessageQueue);
}
@@ -102,7 +143,7 @@
android_os_MessageQueue_getNativeMessageQueue(env, obj);
if (nativeMessageQueue) {
android_os_MessageQueue_setNativeMessageQueue(env, obj, NULL);
- delete nativeMessageQueue;
+ nativeMessageQueue->decStrong(env);
}
}
@@ -113,7 +154,7 @@
static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj,
jint ptr, jint timeoutMillis) {
NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
- nativeMessageQueue->pollOnce(timeoutMillis);
+ nativeMessageQueue->pollOnce(env, timeoutMillis);
}
static void android_os_MessageQueue_nativeWake(JNIEnv* env, jobject obj, jint ptr) {
diff --git a/core/jni/android_os_MessageQueue.h b/core/jni/android_os_MessageQueue.h
index f961d8f..49d2aa0 100644
--- a/core/jni/android_os_MessageQueue.h
+++ b/core/jni/android_os_MessageQueue.h
@@ -18,12 +18,53 @@
#define _ANDROID_OS_MESSAGEQUEUE_H
#include "jni.h"
+#include <utils/Looper.h>
namespace android {
-class Looper;
+class MessageQueue : public RefBase {
+public:
+ /* Gets the message queue's looper. */
+ inline sp<Looper> getLooper() const {
+ return mLooper;
+ }
-extern sp<Looper> android_os_MessageQueue_getLooper(JNIEnv* env, jobject messageQueueObj);
+ /* Checks whether the JNI environment has a pending exception.
+ *
+ * If an exception occurred, logs it together with the specified message,
+ * and calls raiseException() to ensure the exception will be raised when
+ * the callback returns, clears the pending exception from the environment,
+ * then returns true.
+ *
+ * If no exception occurred, returns false.
+ */
+ bool raiseAndClearException(JNIEnv* env, const char* msg);
+
+ /* Raises an exception from within a callback function.
+ * The exception will be rethrown when control returns to the message queue which
+ * will typically cause the application to crash.
+ *
+ * This message can only be called from within a callback function. If it is called
+ * at any other time, the process will simply be killed.
+ *
+ * Does nothing if exception is NULL.
+ *
+ * (This method does not take ownership of the exception object reference.
+ * The caller is responsible for releasing its reference when it is done.)
+ */
+ virtual void raiseException(JNIEnv* env, const char* msg, jthrowable exceptionObj) = 0;
+
+protected:
+ MessageQueue();
+ virtual ~MessageQueue();
+
+protected:
+ sp<Looper> mLooper;
+};
+
+/* Gets the native object associated with a MessageQueue. */
+extern sp<MessageQueue> android_os_MessageQueue_getMessageQueue(
+ JNIEnv* env, jobject messageQueueObj);
} // namespace android
diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp
index 72c171c..d80bfb3 100644
--- a/core/jni/android_view_DisplayEventReceiver.cpp
+++ b/core/jni/android_view_DisplayEventReceiver.cpp
@@ -45,7 +45,7 @@
class NativeDisplayEventReceiver : public RefBase {
public:
NativeDisplayEventReceiver(JNIEnv* env,
- jobject receiverObj, const sp<Looper>& looper);
+ jobject receiverObj, const sp<MessageQueue>& messageQueue);
status_t initialize();
status_t scheduleVsync();
@@ -55,7 +55,7 @@
private:
jobject mReceiverObjGlobal;
- sp<Looper> mLooper;
+ sp<MessageQueue> mMessageQueue;
DisplayEventReceiver mReceiver;
bool mWaitingForVsync;
@@ -65,9 +65,9 @@
NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env,
- jobject receiverObj, const sp<Looper>& looper) :
+ jobject receiverObj, const sp<MessageQueue>& messageQueue) :
mReceiverObjGlobal(env->NewGlobalRef(receiverObj)),
- mLooper(looper), mWaitingForVsync(false) {
+ mMessageQueue(messageQueue), mWaitingForVsync(false) {
ALOGV("receiver %p ~ Initializing input event receiver.", this);
}
@@ -75,7 +75,7 @@
ALOGV("receiver %p ~ Disposing display event receiver.", this);
if (!mReceiver.initCheck()) {
- mLooper->removeFd(mReceiver.getFd());
+ mMessageQueue->getLooper()->removeFd(mReceiver.getFd());
}
JNIEnv* env = AndroidRuntime::getJNIEnv();
@@ -89,7 +89,7 @@
return result;
}
- int rc = mLooper->addFd(mReceiver.getFd(), 0, ALOOPER_EVENT_INPUT,
+ int rc = mMessageQueue->getLooper()->addFd(mReceiver.getFd(), 0, ALOOPER_EVENT_INPUT,
handleReceiveCallback, this);
if (rc < 0) {
return UNKNOWN_ERROR;
@@ -151,12 +151,7 @@
gDisplayEventReceiverClassInfo.dispatchVsync, vsyncTimestamp, vsyncCount);
ALOGV("receiver %p ~ Returned from vsync handler.", data);
- if (env->ExceptionCheck()) {
- ALOGE("An exception occurred while dispatching a vsync event.");
- LOGE_EX(env);
- env->ExceptionClear();
- }
-
+ r->mMessageQueue->raiseAndClearException(env, "dispatchVsync");
return 1; // keep the callback
}
@@ -183,14 +178,14 @@
static jint nativeInit(JNIEnv* env, jclass clazz, jobject receiverObj,
jobject messageQueueObj) {
- sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
- if (looper == NULL) {
+ sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
+ if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env,
- receiverObj, looper);
+ receiverObj, messageQueue);
status_t status = receiver->initialize();
if (status) {
String8 message;
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index e7d4244..348437d 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -48,7 +48,7 @@
public:
NativeInputEventReceiver(JNIEnv* env,
jobject receiverObj, const sp<InputChannel>& inputChannel,
- const sp<Looper>& looper);
+ const sp<MessageQueue>& messageQueue);
status_t initialize();
status_t finishInputEvent(uint32_t seq, bool handled);
@@ -61,7 +61,7 @@
private:
jobject mReceiverObjGlobal;
InputConsumer mInputConsumer;
- sp<Looper> mLooper;
+ sp<MessageQueue> mMessageQueue;
PreallocatedInputEventFactory mInputEventFactory;
bool mBatchedInputEventPending;
@@ -72,9 +72,10 @@
NativeInputEventReceiver::NativeInputEventReceiver(JNIEnv* env,
- jobject receiverObj, const sp<InputChannel>& inputChannel, const sp<Looper>& looper) :
+ jobject receiverObj, const sp<InputChannel>& inputChannel,
+ const sp<MessageQueue>& messageQueue) :
mReceiverObjGlobal(env->NewGlobalRef(receiverObj)),
- mInputConsumer(inputChannel), mLooper(looper),
+ mInputConsumer(inputChannel), mMessageQueue(messageQueue),
mBatchedInputEventPending(false) {
#if DEBUG_DISPATCH_CYCLE
ALOGD("channel '%s' ~ Initializing input event receiver.", getInputChannelName());
@@ -86,7 +87,7 @@
ALOGD("channel '%s' ~ Disposing input event receiver.", getInputChannelName());
#endif
- mLooper->removeFd(mInputConsumer.getChannel()->getFd());
+ mMessageQueue->getLooper()->removeFd(mInputConsumer.getChannel()->getFd());
JNIEnv* env = AndroidRuntime::getJNIEnv();
env->DeleteGlobalRef(mReceiverObjGlobal);
@@ -94,7 +95,8 @@
status_t NativeInputEventReceiver::initialize() {
int receiveFd = mInputConsumer.getChannel()->getFd();
- mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
+ mMessageQueue->getLooper()->addFd(
+ receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
return OK;
}
@@ -157,12 +159,8 @@
#endif
env->CallVoidMethod(mReceiverObjGlobal,
gInputEventReceiverClassInfo.dispatchBatchedInputEventPending);
-
- if (env->ExceptionCheck()) {
- ALOGE("channel '%s' ~ An exception occurred while dispatching that "
- "batched input events are pending.", getInputChannelName());
- LOGE_EX(env);
- env->ExceptionClear();
+ if (mMessageQueue->raiseAndClearException(
+ env, "dispatchBatchedInputEventPending")) {
mBatchedInputEventPending = false; // try again later
}
}
@@ -182,6 +180,7 @@
#endif
inputEventObj = android_view_KeyEvent_fromNative(env,
static_cast<KeyEvent*>(inputEvent));
+ mMessageQueue->raiseAndClearException(env, "new KeyEvent");
break;
case AINPUT_EVENT_TYPE_MOTION:
@@ -190,6 +189,7 @@
#endif
inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
static_cast<MotionEvent*>(inputEvent));
+ mMessageQueue->raiseAndClearException(env, "new MotionEvent");
break;
default:
@@ -200,7 +200,7 @@
if (!inputEventObj) {
ALOGW("channel '%s' ~ Failed to obtain event object.", getInputChannelName());
mInputConsumer.sendFinishedSignal(seq, false);
- return NO_MEMORY;
+ continue;
}
#if DEBUG_DISPATCH_CYCLE
@@ -211,14 +211,8 @@
env->DeleteLocalRef(inputEventObj);
- if (env->ExceptionCheck()) {
- ALOGE("channel '%s' ~ An exception occurred while dispatching an event.",
- getInputChannelName());
- LOGE_EX(env);
- env->ExceptionClear();
-
+ if (mMessageQueue->raiseAndClearException(env, "dispatchInputEvent")) {
mInputConsumer.sendFinishedSignal(seq, false);
- return OK;
}
}
}
@@ -233,14 +227,14 @@
return 0;
}
- sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
- if (looper == NULL) {
+ sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
+ if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
sp<NativeInputEventReceiver> receiver = new NativeInputEventReceiver(env,
- receiverObj, inputChannel, looper);
+ receiverObj, inputChannel, messageQueue);
status_t status = receiver->initialize();
if (status) {
String8 message;
diff --git a/core/res/res/layout/notification_action.xml b/core/res/res/layout/notification_action.xml
index 54fde70..785da7c 100644
--- a/core/res/res/layout/notification_action.xml
+++ b/core/res/res/layout/notification_action.xml
@@ -19,5 +19,5 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@android:style/Widget.Holo.Button.Small"
- android:gravity="left"
+ android:gravity="left|center_vertical"
/>
\ No newline at end of file
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index c7e71eb..41d5c32 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2237,6 +2237,14 @@
* docking station
*/
public static final int DEVICE_OUT_DGTL_DOCK_HEADSET = AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET;
+ /** {@hide} The audio output device code for a USB audio accessory. The accessory is in USB host
+ * mode and the Android device in USB device mode
+ */
+ public static final int DEVICE_OUT_USB_ACCESSORY = AudioSystem.DEVICE_OUT_USB_ACCESSORY;
+ /** {@hide} The audio output device code for a USB audio device. The device is in USB device
+ * mode and the Android device in USB host mode
+ */
+ public static final int DEVICE_OUT_USB_DEVICE = AudioSystem.DEVICE_OUT_USB_DEVICE;
/** {@hide} This is not used as a returned value from {@link #getDevicesForStream}, but could be
* used in the future in a set method to select whatever default device is chosen by the
* platform-specific implementation.
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 2e456f0..48d3712 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -389,9 +389,11 @@
intentFilter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
- intentFilter.addAction(Intent.ACTION_USB_ANLG_HEADSET_PLUG);
- intentFilter.addAction(Intent.ACTION_USB_DGTL_HEADSET_PLUG);
+ intentFilter.addAction(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
+ intentFilter.addAction(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
intentFilter.addAction(Intent.ACTION_HDMI_AUDIO_PLUG);
+ intentFilter.addAction(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG);
+ intentFilter.addAction(Intent.ACTION_USB_AUDIO_DEVICE_PLUG);
intentFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
@@ -2800,6 +2802,28 @@
}
}
+ private boolean handleDeviceConnection(boolean connected, int device, String params) {
+ synchronized (mConnectedDevices) {
+ boolean isConnected = (mConnectedDevices.containsKey(device) &&
+ mConnectedDevices.get(device).equals(params));
+
+ if (isConnected && !connected) {
+ AudioSystem.setDeviceConnectionState(device,
+ AudioSystem.DEVICE_STATE_UNAVAILABLE,
+ params);
+ mConnectedDevices.remove(device);
+ return true;
+ } else if (!isConnected && connected) {
+ AudioSystem.setDeviceConnectionState(device,
+ AudioSystem.DEVICE_STATE_AVAILABLE,
+ params);
+ mConnectedDevices.put(new Integer(device), params);
+ return true;
+ }
+ }
+ return false;
+ }
+
/* cache of the address of the last dock the device was connected to */
private String mDockAddress;
@@ -2810,6 +2834,8 @@
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
+ int device;
+ int state;
if (action.equals(Intent.ACTION_DOCK_EVENT)) {
int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
@@ -2834,15 +2860,15 @@
}
AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config);
} else if (action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) {
- int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
+ state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
BluetoothProfile.STATE_DISCONNECTED);
BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
handleA2dpConnectionStateChange(btDevice, state);
} else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
- int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
+ state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
BluetoothProfile.STATE_DISCONNECTED);
- int device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
+ device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
String address = null;
BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
@@ -2868,129 +2894,56 @@
address = "";
}
- synchronized (mConnectedDevices) {
- boolean isConnected = (mConnectedDevices.containsKey(device) &&
- mConnectedDevices.get(device).equals(address));
-
+ boolean connected = (state == BluetoothProfile.STATE_CONNECTED);
+ if (handleDeviceConnection(connected, device, address)) {
synchronized (mScoClients) {
- if (isConnected && state != BluetoothProfile.STATE_CONNECTED) {
- AudioSystem.setDeviceConnectionState(device,
- AudioSystem.DEVICE_STATE_UNAVAILABLE,
- address);
- mConnectedDevices.remove(device);
+ if (connected) {
+ mBluetoothHeadsetDevice = btDevice;
+ } else {
mBluetoothHeadsetDevice = null;
resetBluetoothSco();
- } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
- AudioSystem.setDeviceConnectionState(device,
- AudioSystem.DEVICE_STATE_AVAILABLE,
- address);
- mConnectedDevices.put(new Integer(device), address);
- mBluetoothHeadsetDevice = btDevice;
}
}
}
} else if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
- int state = intent.getIntExtra("state", 0);
+ state = intent.getIntExtra("state", 0);
int microphone = intent.getIntExtra("microphone", 0);
- synchronized (mConnectedDevices) {
- if (microphone != 0) {
- boolean isConnected =
- mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_WIRED_HEADSET);
- if (state == 0 && isConnected) {
- AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
- AudioSystem.DEVICE_STATE_UNAVAILABLE,
- "");
- mConnectedDevices.remove(AudioSystem.DEVICE_OUT_WIRED_HEADSET);
- } else if (state == 1 && !isConnected) {
- AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
- AudioSystem.DEVICE_STATE_AVAILABLE,
- "");
- mConnectedDevices.put(
- new Integer(AudioSystem.DEVICE_OUT_WIRED_HEADSET), "");
- }
- } else {
- boolean isConnected =
- mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
- if (state == 0 && isConnected) {
- AudioSystem.setDeviceConnectionState(
- AudioSystem.DEVICE_OUT_WIRED_HEADPHONE,
- AudioSystem.DEVICE_STATE_UNAVAILABLE,
- "");
- mConnectedDevices.remove(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
- } else if (state == 1 && !isConnected) {
- AudioSystem.setDeviceConnectionState(
- AudioSystem.DEVICE_OUT_WIRED_HEADPHONE,
- AudioSystem.DEVICE_STATE_AVAILABLE,
- "");
- mConnectedDevices.put(
- new Integer(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE), "");
- }
- }
+ if (microphone != 0) {
+ device = AudioSystem.DEVICE_OUT_WIRED_HEADSET;
+ } else {
+ device = AudioSystem.DEVICE_OUT_WIRED_HEADPHONE;
}
- } else if (action.equals(Intent.ACTION_USB_ANLG_HEADSET_PLUG)) {
- int state = intent.getIntExtra("state", 0);
- Log.v(TAG, "Broadcast Receiver: Got ACTION_USB_ANLG_HEADSET_PLUG, state = "+state);
- synchronized (mConnectedDevices) {
- boolean isConnected =
- mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET);
- if (state == 0 && isConnected) {
- AudioSystem.setDeviceConnectionState(
- AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,
- AudioSystem.DEVICE_STATE_UNAVAILABLE,
- "");
- mConnectedDevices.remove(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET);
- } else if (state == 1 && !isConnected) {
- AudioSystem.setDeviceConnectionState(
- AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,
- AudioSystem.DEVICE_STATE_AVAILABLE,
- "");
- mConnectedDevices.put(
- new Integer(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET), "");
- }
- }
+ handleDeviceConnection((state == 1), device, "");
+ } else if (action.equals(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG)) {
+ state = intent.getIntExtra("state", 0);
+ Log.v(TAG, "Broadcast Receiver: Got ACTION_ANALOG_AUDIO_DOCK_PLUG, state = "+state);
+ handleDeviceConnection((state == 1), AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, "");
} else if (action.equals(Intent.ACTION_HDMI_AUDIO_PLUG)) {
- int state = intent.getIntExtra("state", 0);
+ state = intent.getIntExtra("state", 0);
Log.v(TAG, "Broadcast Receiver: Got ACTION_HDMI_AUDIO_PLUG, state = "+state);
- synchronized (mConnectedDevices) {
- boolean isConnected =
- mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_AUX_DIGITAL);
- if (state == 0 && isConnected) {
- AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_AUX_DIGITAL,
- AudioSystem.DEVICE_STATE_UNAVAILABLE,
- "");
- mConnectedDevices.remove(AudioSystem.DEVICE_OUT_AUX_DIGITAL);
- } else if (state == 1 && !isConnected) {
- AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_AUX_DIGITAL,
- AudioSystem.DEVICE_STATE_AVAILABLE,
- "");
- mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_AUX_DIGITAL), "");
- }
- }
- } else if (action.equals(Intent.ACTION_USB_DGTL_HEADSET_PLUG)) {
- int state = intent.getIntExtra("state", 0);
- Log.v(TAG, "Broadcast Receiver: Got ACTION_USB_DGTL_HEADSET_PLUG, state = "+state);
- synchronized (mConnectedDevices) {
- boolean isConnected =
- mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET);
- if (state == 0 && isConnected) {
- AudioSystem.setDeviceConnectionState(
- AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET,
- AudioSystem.DEVICE_STATE_UNAVAILABLE,
- "");
- mConnectedDevices.remove(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET);
- } else if (state == 1 && !isConnected) {
- AudioSystem.setDeviceConnectionState(
- AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET,
- AudioSystem.DEVICE_STATE_AVAILABLE,
- "");
- mConnectedDevices.put(
- new Integer(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET), "");
- }
- }
+ handleDeviceConnection((state == 1), AudioSystem.DEVICE_OUT_AUX_DIGITAL, "");
+ } else if (action.equals(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG)) {
+ state = intent.getIntExtra("state", 0);
+ Log.v(TAG,
+ "Broadcast Receiver Got ACTION_DIGITAL_AUDIO_DOCK_PLUG, state = " + state);
+ handleDeviceConnection((state == 1), AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET, "");
+ } else if (action.equals(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG) ||
+ action.equals(Intent.ACTION_USB_AUDIO_DEVICE_PLUG)) {
+ state = intent.getIntExtra("state", 0);
+ int alsaCard = intent.getIntExtra("card", -1);
+ int alsaDevice = intent.getIntExtra("device", -1);
+ String params = "card=" + alsaCard + ";device=" + alsaDevice;
+ device = action.equals(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG) ?
+ AudioSystem.DEVICE_OUT_USB_ACCESSORY : AudioSystem.DEVICE_OUT_USB_DEVICE;
+ Log.v(TAG, "Broadcast Receiver: Got "
+ + (action.equals(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG) ?
+ "ACTION_USB_AUDIO_ACCESSORY_PLUG" : "ACTION_USB_AUDIO_DEVICE_PLUG")
+ + ", state = " + state + ", card: " + alsaCard + ", device: " + alsaDevice);
+ handleDeviceConnection((state == 1), device, params);
} else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
boolean broadcast = false;
- int state = AudioManager.SCO_AUDIO_STATE_ERROR;
+ int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR;
synchronized (mScoClients) {
int btState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
// broadcast intent if the connection was initated by AudioService
@@ -3002,7 +2955,7 @@
}
switch (btState) {
case BluetoothHeadset.STATE_AUDIO_CONNECTED:
- state = AudioManager.SCO_AUDIO_STATE_CONNECTED;
+ scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTED;
if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL &&
mScoAudioState != SCO_STATE_DEACTIVATE_REQ &&
mScoAudioState != SCO_STATE_DEACTIVATE_EXT_REQ) {
@@ -3010,7 +2963,7 @@
}
break;
case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
- state = AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
+ scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
mScoAudioState = SCO_STATE_INACTIVE;
clearAllScoClients(0, false);
break;
@@ -3027,11 +2980,11 @@
}
}
if (broadcast) {
- broadcastScoConnectionState(state);
+ broadcastScoConnectionState(scoAudioState);
//FIXME: this is to maintain compatibility with deprecated intent
// AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED. Remove when appropriate.
Intent newIntent = new Intent(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED);
- newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, state);
+ newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, scoAudioState);
mContext.sendStickyBroadcast(newIntent);
}
} else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 18a00bc..9bafa5c 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -202,6 +202,9 @@
public static final int DEVICE_OUT_AUX_DIGITAL = 0x400;
public static final int DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800;
public static final int DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000;
+ public static final int DEVICE_OUT_USB_ACCESSORY = 0x2000;
+ public static final int DEVICE_OUT_USB_DEVICE = 0x4000;
+
public static final int DEVICE_OUT_DEFAULT = 0x8000;
public static final int DEVICE_OUT_ALL = (DEVICE_OUT_EARPIECE |
DEVICE_OUT_SPEAKER |
@@ -216,10 +219,18 @@
DEVICE_OUT_AUX_DIGITAL |
DEVICE_OUT_ANLG_DOCK_HEADSET |
DEVICE_OUT_DGTL_DOCK_HEADSET |
+ DEVICE_OUT_USB_ACCESSORY |
+ DEVICE_OUT_USB_DEVICE |
DEVICE_OUT_DEFAULT);
public static final int DEVICE_OUT_ALL_A2DP = (DEVICE_OUT_BLUETOOTH_A2DP |
DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER);
+ public static final int DEVICE_OUT_ALL_SCO = (DEVICE_OUT_BLUETOOTH_SCO |
+ DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
+ DEVICE_OUT_BLUETOOTH_SCO_CARKIT);
+ public static final int DEVICE_OUT_ALL_USB = (DEVICE_OUT_USB_ACCESSORY |
+ DEVICE_OUT_USB_DEVICE);
+
// input devices
public static final int DEVICE_IN_COMMUNICATION = 0x10000;
public static final int DEVICE_IN_AMBIENT = 0x20000;
diff --git a/services/java/com/android/server/WiredAccessoryObserver.java b/services/java/com/android/server/WiredAccessoryObserver.java
index 9b4eddc..53d1f0e 100644
--- a/services/java/com/android/server/WiredAccessoryObserver.java
+++ b/services/java/com/android/server/WiredAccessoryObserver.java
@@ -301,13 +301,13 @@
// Pack up the values and broadcast them to everyone
if (headset == BIT_USB_HEADSET_ANLG) {
- intent = new Intent(Intent.ACTION_USB_ANLG_HEADSET_PLUG);
+ intent = new Intent(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtra("state", state);
intent.putExtra("name", headsetName);
ActivityManagerNative.broadcastStickyIntent(intent, null);
} else if (headset == BIT_USB_HEADSET_DGTL) {
- intent = new Intent(Intent.ACTION_USB_DGTL_HEADSET_PLUG);
+ intent = new Intent(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtra("state", state);
intent.putExtra("name", headsetName);
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index d60ff2b..a098f18 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -16,6 +16,7 @@
package com.android.server.am;
+import com.android.internal.app.ResolverActivity;
import com.android.server.AttributeCache;
import com.android.server.am.ActivityStack.ActivityState;
@@ -382,7 +383,7 @@
_intent.getData() == null &&
_intent.getType() == null &&
(intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
- !"android".equals(realActivity.getClassName())) {
+ !ResolverActivity.class.getName().equals(realActivity.getClassName())) {
// This sure looks like a home activity!
// Note the last check is so we don't count the resolver
// activity as being home... really, we don't care about
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index f7ba329..519d58e 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -500,6 +500,9 @@
Binder.restoreCallingIdentity(token);
}
+ // splice in operation counts
+ networkLayer.spliceOperationsFrom(mUidOperations);
+
final NetworkStats dataLayer = new NetworkStats(
networkLayer.getElapsedRealtime(), networkLayer.size());
@@ -510,8 +513,6 @@
dataLayer.combineValues(entry);
}
- // splice in operation counts
- dataLayer.spliceOperationsFrom(mUidOperations);
return dataLayer;
}
diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java
index 003dc17..c3b5465 100644
--- a/services/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/java/com/android/server/wm/AppWindowAnimator.java
@@ -224,7 +224,7 @@
hasTransformation = false;
- if (!animating) {
+ if (!animating && animation == null) {
return false;
}
diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp
index c57402f..75c20f3 100644
--- a/services/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/jni/com_android_server_input_InputManagerService.cpp
@@ -950,8 +950,9 @@
static jint nativeInit(JNIEnv* env, jclass clazz,
jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
- sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
- NativeInputManager* im = new NativeInputManager(contextObj, serviceObj, looper);
+ sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
+ NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
+ messageQueue->getLooper());
im->incStrong(serviceObj);
return reinterpret_cast<jint>(im);
}