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;