diff options
| -rw-r--r-- | core/java/android/hardware/SystemSensorManager.java | 8 | ||||
| -rw-r--r-- | core/java/android/view/DisplayEventReceiver.java | 6 | ||||
| -rw-r--r-- | core/jni/android_hardware_SensorManager.cpp | 39 | ||||
| -rw-r--r-- | core/jni/android_view_DisplayEventReceiver.cpp | 40 |
4 files changed, 56 insertions, 37 deletions
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java index 88fa339a53cb..7ad3a683cd6f 100644 --- a/core/java/android/hardware/SystemSensorManager.java +++ b/core/java/android/hardware/SystemSensorManager.java @@ -26,6 +26,7 @@ import android.util.SparseBooleanArray; import android.util.SparseIntArray; import dalvik.system.CloseGuard; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -224,8 +225,8 @@ public class SystemSensorManager extends SensorManager { * the queues and the listeners. */ private static abstract class BaseEventQueue { - private native long nativeInitBaseEventQueue(BaseEventQueue eventQ, MessageQueue msgQ, - float[] scratch, String packageName); + private native long nativeInitBaseEventQueue(WeakReference<BaseEventQueue> eventQWeak, + MessageQueue msgQ, float[] scratch, String packageName); private static native int nativeEnableSensor(long eventQ, int handle, int rateUs, int maxBatchReportLatencyUs); private static native int nativeDisableSensor(long eventQ, int handle); @@ -240,7 +241,8 @@ public class SystemSensorManager extends SensorManager { protected final SystemSensorManager mManager; BaseEventQueue(Looper looper, SystemSensorManager manager) { - nSensorEventQueue = nativeInitBaseEventQueue(this, looper.getQueue(), mScratch, + nSensorEventQueue = nativeInitBaseEventQueue(new WeakReference<BaseEventQueue>(this), + looper.getQueue(), mScratch, manager.mPackageName); mCloseGuard.open("dispose"); mManager = manager; diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java index de46a4a8f642..5a9a1eacbef6 100644 --- a/core/java/android/view/DisplayEventReceiver.java +++ b/core/java/android/view/DisplayEventReceiver.java @@ -22,6 +22,8 @@ import android.os.Looper; import android.os.MessageQueue; import android.util.Log; +import java.lang.ref.WeakReference; + /** * Provides a low-level mechanism for an application to receive display events * such as vertical sync. @@ -42,7 +44,7 @@ public abstract class DisplayEventReceiver { // GC'd while the native peer of the receiver is using them. private MessageQueue mMessageQueue; - private static native long nativeInit(DisplayEventReceiver receiver, + private static native long nativeInit(WeakReference<DisplayEventReceiver> receiver, MessageQueue messageQueue); private static native void nativeDispose(long receiverPtr); private static native void nativeScheduleVsync(long receiverPtr); @@ -58,7 +60,7 @@ public abstract class DisplayEventReceiver { } mMessageQueue = looper.getQueue(); - mReceiverPtr = nativeInit(this, mMessageQueue); + mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue); mCloseGuard.open("dispose"); } diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp index 7d122303e1fa..16e5b3cf27df 100644 --- a/core/jni/android_hardware_SensorManager.cpp +++ b/core/jni/android_hardware_SensorManager.cpp @@ -19,6 +19,7 @@ #include <map> #include <ScopedUtfChars.h> +#include <ScopedLocalRef.h> #include <utils/Log.h> #include <utils/Looper.h> @@ -178,21 +179,21 @@ nativeGetNextSensor(JNIEnv *env, jclass clazz, jobject sensor, jint next) class Receiver : public LooperCallback { sp<SensorEventQueue> mSensorQueue; sp<MessageQueue> mMessageQueue; - jobject mReceiverObject; + jobject mReceiverWeakGlobal; jfloatArray mScratch; public: Receiver(const sp<SensorEventQueue>& sensorQueue, const sp<MessageQueue>& messageQueue, - jobject receiverObject, jfloatArray scratch) { + jobject receiverWeak, jfloatArray scratch) { JNIEnv* env = AndroidRuntime::getJNIEnv(); mSensorQueue = sensorQueue; mMessageQueue = messageQueue; - mReceiverObject = env->NewGlobalRef(receiverObject); + mReceiverWeakGlobal = env->NewGlobalRef(receiverWeak); mScratch = (jfloatArray)env->NewGlobalRef(scratch); } ~Receiver() { JNIEnv* env = AndroidRuntime::getJNIEnv(); - env->DeleteGlobalRef(mReceiverObject); + env->DeleteGlobalRef(mReceiverWeakGlobal); env->DeleteGlobalRef(mScratch); } sp<SensorEventQueue> getSensorEventQueue() const { @@ -213,6 +214,8 @@ private: virtual int handleEvent(int fd, int events, void* data) { JNIEnv* env = AndroidRuntime::getJNIEnv(); sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data); + ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal)); + ssize_t n; ASensorEvent buffer[16]; while ((n = q->read(buffer, 16)) > 0) { @@ -228,9 +231,11 @@ private: if (buffer[i].type == SENSOR_TYPE_META_DATA) { // This is a flush complete sensor event. Call dispatchFlushCompleteEvent // method. - env->CallVoidMethod(mReceiverObject, - gBaseEventQueueClassInfo.dispatchFlushCompleteEvent, - buffer[i].meta_data.sensor); + if (receiverObj.get()) { + env->CallVoidMethod(receiverObj.get(), + gBaseEventQueueClassInfo.dispatchFlushCompleteEvent, + buffer[i].meta_data.sensor); + } } else { int8_t status; switch (buffer[i].type) { @@ -247,12 +252,14 @@ private: status = SENSOR_STATUS_ACCURACY_HIGH; break; } - env->CallVoidMethod(mReceiverObject, - gBaseEventQueueClassInfo.dispatchSensorEvent, - buffer[i].sensor, - mScratch, - status, - buffer[i].timestamp); + if (receiverObj.get()) { + env->CallVoidMethod(receiverObj.get(), + gBaseEventQueueClassInfo.dispatchSensorEvent, + buffer[i].sensor, + mScratch, + status, + buffer[i].timestamp); + } } if (env->ExceptionCheck()) { mSensorQueue->sendAck(buffer, n); @@ -269,7 +276,7 @@ private: } }; -static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jobject eventQ, jobject msgQ, +static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jobject eventQWeak, jobject msgQ, jfloatArray scratch, jstring packageName) { SensorManager& mgr(SensorManager::getInstance()); ScopedUtfChars packageUtf(env, packageName); @@ -282,7 +289,7 @@ static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jobject event return 0; } - sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQ, scratch); + sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak, scratch); receiver->incStrong((void*)nativeInitSensorEventQueue); return jlong(receiver.get()); } @@ -325,7 +332,7 @@ static JNINativeMethod gSystemSensorManagerMethods[] = { static JNINativeMethod gBaseEventQueueMethods[] = { {"nativeInitBaseEventQueue", - "(Landroid/hardware/SystemSensorManager$BaseEventQueue;Landroid/os/MessageQueue;[FLjava/lang/String;)J", + "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;[FLjava/lang/String;)J", (void*)nativeInitSensorEventQueue }, {"nativeEnableSensor", diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp index 0d5495356fad..91a3c7e6891f 100644 --- a/core/jni/android_view_DisplayEventReceiver.cpp +++ b/core/jni/android_view_DisplayEventReceiver.cpp @@ -29,6 +29,8 @@ #include <gui/DisplayEventReceiver.h> #include "android_os_MessageQueue.h" +#include <ScopedLocalRef.h> + #include "core_jni_helpers.h" namespace android { @@ -49,7 +51,7 @@ static struct { class NativeDisplayEventReceiver : public LooperCallback { public: NativeDisplayEventReceiver(JNIEnv* env, - jobject receiverObj, const sp<MessageQueue>& messageQueue); + jobject receiverWeak, const sp<MessageQueue>& messageQueue); status_t initialize(); void dispose(); @@ -59,7 +61,7 @@ protected: virtual ~NativeDisplayEventReceiver(); private: - jobject mReceiverObjGlobal; + jobject mReceiverWeakGlobal; sp<MessageQueue> mMessageQueue; DisplayEventReceiver mReceiver; bool mWaitingForVsync; @@ -72,15 +74,15 @@ private: NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, - jobject receiverObj, const sp<MessageQueue>& messageQueue) : - mReceiverObjGlobal(env->NewGlobalRef(receiverObj)), + jobject receiverWeak, const sp<MessageQueue>& messageQueue) : + mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)), mMessageQueue(messageQueue), mWaitingForVsync(false) { ALOGV("receiver %p ~ Initializing input event receiver.", this); } NativeDisplayEventReceiver::~NativeDisplayEventReceiver() { JNIEnv* env = AndroidRuntime::getJNIEnv(); - env->DeleteGlobalRef(mReceiverObjGlobal); + env->DeleteGlobalRef(mReceiverWeakGlobal); } status_t NativeDisplayEventReceiver::initialize() { @@ -190,10 +192,13 @@ bool NativeDisplayEventReceiver::processPendingEvents( void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - ALOGV("receiver %p ~ Invoking vsync handler.", this); - env->CallVoidMethod(mReceiverObjGlobal, - gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, id, count); - ALOGV("receiver %p ~ Returned from vsync handler.", this); + ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal)); + if (receiverObj.get()) { + ALOGV("receiver %p ~ Invoking vsync handler.", this); + env->CallVoidMethod(receiverObj.get(), + gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, id, count); + ALOGV("receiver %p ~ Returned from vsync handler.", this); + } mMessageQueue->raiseAndClearException(env, "dispatchVsync"); } @@ -201,16 +206,19 @@ void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, int32_t id, ui void NativeDisplayEventReceiver::dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - ALOGV("receiver %p ~ Invoking hotplug handler.", this); - env->CallVoidMethod(mReceiverObjGlobal, - gDisplayEventReceiverClassInfo.dispatchHotplug, timestamp, id, connected); - ALOGV("receiver %p ~ Returned from hotplug handler.", this); + ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal)); + if (receiverObj.get()) { + ALOGV("receiver %p ~ Invoking hotplug handler.", this); + env->CallVoidMethod(receiverObj.get(), + gDisplayEventReceiverClassInfo.dispatchHotplug, timestamp, id, connected); + ALOGV("receiver %p ~ Returned from hotplug handler.", this); + } mMessageQueue->raiseAndClearException(env, "dispatchHotplug"); } -static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverObj, +static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj) { sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); if (messageQueue == NULL) { @@ -219,7 +227,7 @@ static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverObj, } sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env, - receiverObj, messageQueue); + receiverWeak, messageQueue); status_t status = receiver->initialize(); if (status) { String8 message; @@ -254,7 +262,7 @@ static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) { static JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ { "nativeInit", - "(Landroid/view/DisplayEventReceiver;Landroid/os/MessageQueue;)J", + "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;)J", (void*)nativeInit }, { "nativeDispose", "(J)V", |