Fix leaks due to GC circular references.
The DisplayEventReceiver and SensorManager event queue both get
leaked when the Looper thread they are attached to dies because
the Java object holds a strong reference to its native peer and
meanwhile the native peer holds a strong reference to the Java
object through JNI.
Fixed the issue by indirecting through a weak reference as was
done for InputEventReceiver some time ago.
Bug: 12455729
Change-Id: I3d80a2a190192d1a2981bf5ae0cad30f0f7688a5
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index 88fa339..7ad3a68 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -26,6 +26,7 @@
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 @@
* 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 @@
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;