Merge "batstats: fix wake lock tracking, service bug"
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 8aee4db..a4374b8 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -590,7 +590,6 @@
                 return false;
             }
             mAdvertisingGattCallback.stopAdvertising();
-            mAdvertisingGattCallback = null;
             return true;
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
@@ -1794,15 +1793,12 @@
                     try {
                         IBluetoothGatt iGatt = adapter.getBluetoothManager().getBluetoothGatt();
                         iGatt.stopAdvertising();
-                        Log.d(TAG, "unregistering client " + mLeHandle);
-                        iGatt.unregisterClient(mLeHandle);
                     } catch (RemoteException e) {
-                        Log.e(TAG, "Failed to stop advertising and unregister" + e);
+                        Log.e(TAG, "Failed to stop advertising" + e);
                     }
                 } else {
                     Log.e(TAG, "stopAdvertising, BluetoothAdapter is null");
                 }
-                mLeHandle = -1;
                 notifyAll();
             }
         }
@@ -1992,6 +1988,26 @@
             if (advertiseState == STATE_ADVERTISE_STARTED) {
                 mAdvertiseCallback.onAdvertiseStart(status);
             } else {
+                synchronized (this) {
+                    if (status == ADVERTISE_CALLBACK_SUCCESS) {
+                        BluetoothAdapter adapter = mBluetoothAdapter.get();
+                        if (adapter != null) {
+                            try {
+                                IBluetoothGatt iGatt =
+                                        adapter.getBluetoothManager().getBluetoothGatt();
+                                Log.d(TAG, "unregistering client " + mLeHandle);
+                                iGatt.unregisterClient(mLeHandle);
+                                // Reset advertise app handle.
+                                mLeHandle = -1;
+                                adapter.mAdvertisingGattCallback = null;
+                            } catch (RemoteException e) {
+                                Log.e(TAG, "Failed to unregister client" + e);
+                            }
+                        } else {
+                            Log.e(TAG, "cannot unregister client, BluetoothAdapter is null");
+                        }
+                    }
+                }
                 mAdvertiseCallback.onAdvertiseStop(status);
             }
         }
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 6e2a099..35c86e7 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -45,6 +45,7 @@
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 
 /**
@@ -2149,10 +2150,20 @@
         private static final String PIXEL_FORMAT_JPEG = "jpeg";
         private static final String PIXEL_FORMAT_BAYER_RGGB = "bayer-rggb";
 
-        private HashMap<String, String> mMap;
+        /**
+         * Order matters: Keys that are {@link #set(String, String) set} later
+         * will take precedence over keys that are set earlier (if the two keys
+         * conflict with each other).
+         *
+         * <p>One example is {@link #setPreviewFpsRange(int, int)} , since it
+         * conflicts with {@link #setPreviewFrameRate(int)} whichever key is set later
+         * is the one that will take precedence.
+         * </p>
+         */
+        private final LinkedHashMap<String, String> mMap;
 
         private Parameters() {
-            mMap = new HashMap<String, String>(64);
+            mMap = new LinkedHashMap<String, String>(/*initialCapacity*/64);
         }
 
         /**
@@ -2232,7 +2243,7 @@
                 return;
             }
 
-            mMap.put(key, value);
+            put(key, value);
         }
 
         /**
@@ -2242,7 +2253,18 @@
          * @param value the int value of the parameter
          */
         public void set(String key, int value) {
-            mMap.put(key, Integer.toString(value));
+            put(key, Integer.toString(value));
+        }
+
+        private void put(String key, String value) {
+            /*
+             * Remove the key if it already exists.
+             *
+             * This way setting a new value for an already existing key will always move
+             * that key to be ordered the latest in the map.
+             */
+            mMap.remove(key);
+            mMap.put(key, value);
         }
 
         private void set(String key, List<Area> areas) {
diff --git a/media/java/android/media/MediaHTTPConnection.java b/media/java/android/media/MediaHTTPConnection.java
index 67680a8..eb91668 100644
--- a/media/java/android/media/MediaHTTPConnection.java
+++ b/media/java/android/media/MediaHTTPConnection.java
@@ -269,6 +269,6 @@
         native_init();
     }
 
-    private int mNativeContext;
+    private long mNativeContext;
 
 }
diff --git a/media/jni/android_media_MediaHTTPConnection.cpp b/media/jni/android_media_MediaHTTPConnection.cpp
index c48af11..da3f74d 100644
--- a/media/jni/android_media_MediaHTTPConnection.cpp
+++ b/media/jni/android_media_MediaHTTPConnection.cpp
@@ -84,7 +84,7 @@
 static sp<JMediaHTTPConnection> setObject(
         JNIEnv *env, jobject thiz, const sp<JMediaHTTPConnection> &conn) {
     sp<JMediaHTTPConnection> old =
-        (JMediaHTTPConnection *)env->GetIntField(thiz, gFields.context);
+        (JMediaHTTPConnection *)env->GetLongField(thiz, gFields.context);
 
     if (conn != NULL) {
         conn->incStrong(thiz);
@@ -92,13 +92,13 @@
     if (old != NULL) {
         old->decStrong(thiz);
     }
-    env->SetIntField(thiz, gFields.context, (int)conn.get());
+    env->SetLongField(thiz, gFields.context, (jlong)conn.get());
 
     return old;
 }
 
 static sp<JMediaHTTPConnection> getObject(JNIEnv *env, jobject thiz) {
-    return (JMediaHTTPConnection *)env->GetIntField(thiz, gFields.context);
+    return (JMediaHTTPConnection *)env->GetLongField(thiz, gFields.context);
 }
 
 static void android_media_MediaHTTPConnection_native_init(JNIEnv *env) {