Merge "wifi: add ParcelUtil for parcelizing non-parcelable objects"
diff --git a/api/current.txt b/api/current.txt
index a1e8337..b391b00 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -59117,8 +59117,10 @@
     method public java.util.Set<java.lang.String> getUnicodeLocaleKeys();
     method public java.lang.String getUnicodeLocaleType(java.lang.String);
     method public java.lang.String getVariant();
+    method public boolean hasExtensions();
     method public static synchronized void setDefault(java.util.Locale);
     method public static synchronized void setDefault(java.util.Locale.Category, java.util.Locale);
+    method public java.util.Locale stripExtensions();
     method public java.lang.String toLanguageTag();
     method public final java.lang.String toString();
     field public static final java.util.Locale CANADA;
diff --git a/api/system-current.txt b/api/system-current.txt
index 0787091..68c7b48 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -62474,8 +62474,10 @@
     method public java.util.Set<java.lang.String> getUnicodeLocaleKeys();
     method public java.lang.String getUnicodeLocaleType(java.lang.String);
     method public java.lang.String getVariant();
+    method public boolean hasExtensions();
     method public static synchronized void setDefault(java.util.Locale);
     method public static synchronized void setDefault(java.util.Locale.Category, java.util.Locale);
+    method public java.util.Locale stripExtensions();
     method public java.lang.String toLanguageTag();
     method public final java.lang.String toString();
     field public static final java.util.Locale CANADA;
diff --git a/api/test-current.txt b/api/test-current.txt
index d8936b6..2aa6cfe 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -59197,8 +59197,10 @@
     method public java.util.Set<java.lang.String> getUnicodeLocaleKeys();
     method public java.lang.String getUnicodeLocaleType(java.lang.String);
     method public java.lang.String getVariant();
+    method public boolean hasExtensions();
     method public static synchronized void setDefault(java.util.Locale);
     method public static synchronized void setDefault(java.util.Locale.Category, java.util.Locale);
+    method public java.util.Locale stripExtensions();
     method public java.lang.String toLanguageTag();
     method public final java.lang.String toString();
     field public static final java.util.Locale CANADA;
diff --git a/core/java/android/os/IRecoverySystem.aidl b/core/java/android/os/IRecoverySystem.aidl
index 12830a4..c5ceecd 100644
--- a/core/java/android/os/IRecoverySystem.aidl
+++ b/core/java/android/os/IRecoverySystem.aidl
@@ -25,4 +25,5 @@
     boolean uncrypt(in String packageFile, IRecoverySystemProgressListener listener);
     boolean setupBcb(in String command);
     boolean clearBcb();
+    void rebootRecoveryWithCommand(in String command);
 }
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 2d5a144..662e14c 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -671,28 +671,22 @@
      * @throws IOException if something goes wrong.
      */
     private static void bootCommand(Context context, String... args) throws IOException {
-        synchronized (sRequestLock) {
-            LOG_FILE.delete();
+        LOG_FILE.delete();
 
-            StringBuilder command = new StringBuilder();
-            for (String arg : args) {
-                if (!TextUtils.isEmpty(arg)) {
-                    command.append(arg);
-                    command.append("\n");
-                }
+        StringBuilder command = new StringBuilder();
+        for (String arg : args) {
+            if (!TextUtils.isEmpty(arg)) {
+                command.append(arg);
+                command.append("\n");
             }
-
-            // Write the command into BCB (bootloader control block).
-            RecoverySystem rs = (RecoverySystem) context.getSystemService(
-                    Context.RECOVERY_SERVICE);
-            rs.setupBcb(command.toString());
-
-            // Having set up the BCB, go ahead and reboot.
-            PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-            pm.reboot(PowerManager.REBOOT_RECOVERY);
-
-            throw new IOException("Reboot failed (no permissions?)");
         }
+
+        // Write the command into BCB (bootloader control block) and boot from
+        // there. Will not return unless failed.
+        RecoverySystem rs = (RecoverySystem) context.getSystemService(Context.RECOVERY_SERVICE);
+        rs.rebootRecoveryWithCommand(command.toString());
+
+        throw new IOException("Reboot failed (no permissions?)");
     }
 
     // Read last_install; then report time (in seconds) and I/O (in MiB) for
@@ -887,6 +881,17 @@
     }
 
     /**
+     * Talks to RecoverySystemService via Binder to set up the BCB command and
+     * reboot into recovery accordingly.
+     */
+    private void rebootRecoveryWithCommand(String command) {
+        try {
+            mService.rebootRecoveryWithCommand(command);
+        } catch (RemoteException ignored) {
+        }
+    }
+
+    /**
      * Internally, recovery treats each line of the command file as a separate
      * argv, so we only need to protect against newlines and nulls.
      */
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 97c7f04..ba9facf 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -430,6 +430,8 @@
     char tmp[128];
     FILE *fp;
 
+    *foundSwapPss = false;
+
     sprintf(tmp, "/proc/%d/smaps", pid);
     fp = fopen(tmp, "r");
     if (fp == 0) return;
diff --git a/core/jni/android_os_HwBinder.cpp b/core/jni/android_os_HwBinder.cpp
index 7da0314..13e3f0d 100644
--- a/core/jni/android_os_HwBinder.cpp
+++ b/core/jni/android_os_HwBinder.cpp
@@ -266,6 +266,9 @@
         return NULL;
     }
 
+    LOG(INFO) << "Starting thread pool.";
+    ::android::hardware::ProcessState::self()->startThreadPool();
+
     return JHwRemoteBinder::NewObject(env, service);
 }
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b0b57d9..ae560f9 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -289,6 +289,7 @@
     <protected-broadcast android:name="android.net.wifi.WIFI_AP_STATE_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.WIFI_CREDENTIAL_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.WIFI_SCAN_AVAILABLE" />
+    <protected-broadcast android:name="android.net.wifi.nan.action.WIFI_NAN_STATE_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.SCAN_RESULTS" />
     <protected-broadcast android:name="android.net.wifi.RSSI_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.STATE_CHANGE" />
diff --git a/core/res/res/values-mcc238-mnc06/config.xml b/core/res/res/values-mcc238-mnc06/config.xml
deleted file mode 100644
index afc0cc4..0000000
--- a/core/res/res/values-mcc238-mnc06/config.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2014, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- SIM does not save, but the voice mail number to be changed. -->
-    <bool name="editable_voicemailnumber">true</bool>
-</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 51a5704..f9096956 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2157,6 +2157,11 @@
     <!-- Flag specifying whether WFC over IMS is available on device -->
     <bool name="config_device_wfc_ims_available">false</bool>
 
+    <!-- Flag specifying whether WFC over IMS should be available for carrier: independent of
+         carrier provisioning. If false: hard disabled. If true: then depends on carrier
+         provisioning, availability etc -->
+    <bool name="config_carrier_wfc_ims_available">false</bool>
+
     <bool name="config_networkSamplingWakesDevice">true</bool>
 
     <string-array translatable="false" name="config_cdma_home_system" />
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 72e5078..a51b29c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -345,8 +345,6 @@
   <java-symbol type="integer"  name="config_wifi_operating_voltage_mv" />
   <java-symbol type="string"  name="config_wifi_framework_sap_2G_channel_list" />
 
-  <java-symbol type="bool" name="editable_voicemailnumber" />
-
   <java-symbol type="bool" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment" />
   <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_tx_packet_threshold" />
   <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_rx_packet_threshold" />
@@ -2195,6 +2193,7 @@
   <java-symbol type="bool" name="config_device_vt_available" />
   <java-symbol type="bool" name="config_carrier_vt_available" />
   <java-symbol type="bool" name="config_device_wfc_ims_available" />
+  <java-symbol type="bool" name="config_carrier_wfc_ims_available" />
   <java-symbol type="attr" name="touchscreenBlocksFocus" />
   <java-symbol type="layout" name="resolver_list_with_default" />
   <java-symbol type="string" name="whichApplicationNamed" />
diff --git a/core/tests/systemproperties/Android.mk b/core/tests/systemproperties/Android.mk
index ffc1282..e16c367 100644
--- a/core/tests/systemproperties/Android.mk
+++ b/core/tests/systemproperties/Android.mk
@@ -11,7 +11,6 @@
 LOCAL_STATIC_JAVA_LIBRARIES := android-common frameworks-core-util-lib
 LOCAL_JAVA_LIBRARIES := android.test.runner
 LOCAL_PACKAGE_NAME := FrameworksCoreSystemPropertiesTests
-LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 
 LOCAL_CERTIFICATE := platform
 
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index f50cff4..8ea25d6 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -1892,6 +1892,7 @@
 
 Asset* AssetManager::SharedZip::getResourceTableAsset()
 {
+    AutoMutex _l(gLock);
     ALOGV("Getting from SharedZip %p resource asset %p\n", this, mResourceTableAsset);
     return mResourceTableAsset;
 }
@@ -1901,10 +1902,10 @@
     {
         AutoMutex _l(gLock);
         if (mResourceTableAsset == NULL) {
-            mResourceTableAsset = asset;
             // This is not thread safe the first time it is called, so
             // do it here with the global lock held.
             asset->getBuffer(true);
+            mResourceTableAsset = asset;
             return asset;
         }
     }
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index c0c47ef..d68bb53 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -31,7 +31,7 @@
 struct AMessage;
 struct AString;
 struct ICrypto;
-struct IGraphicBufferProducer;
+class IGraphicBufferProducer;
 struct MediaCodec;
 struct PersistentSurface;
 class Surface;
diff --git a/media/tests/MediaFrameworkTest/Android.mk b/media/tests/MediaFrameworkTest/Android.mk
index 7e438a1..29557be 100644
--- a/media/tests/MediaFrameworkTest/Android.mk
+++ b/media/tests/MediaFrameworkTest/Android.mk
@@ -7,8 +7,6 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
-LOCAL_JAVA_LANGUAGE_VERSION := 1.8
-
 LOCAL_STATIC_JAVA_LIBRARIES := easymocklib \
     mockito-target \
     android-support-test \
diff --git a/services/core/java/com/android/server/RecoverySystemService.java b/services/core/java/com/android/server/RecoverySystemService.java
index 276687f..3c8c699 100644
--- a/services/core/java/com/android/server/RecoverySystemService.java
+++ b/services/core/java/com/android/server/RecoverySystemService.java
@@ -21,6 +21,7 @@
 import android.net.LocalSocketAddress;
 import android.os.IRecoverySystem;
 import android.os.IRecoverySystemProgressListener;
+import android.os.PowerManager;
 import android.os.RecoverySystem;
 import android.os.RemoteException;
 import android.os.SystemProperties;
@@ -50,8 +51,15 @@
     // The socket at /dev/socket/uncrypt to communicate with uncrypt.
     private static final String UNCRYPT_SOCKET = "uncrypt";
 
+    // The init services that communicate with /system/bin/uncrypt.
+    private static final String INIT_SERVICE_UNCRYPT = "init.svc.uncrypt";
+    private static final String INIT_SERVICE_SETUP_BCB = "init.svc.setup-bcb";
+    private static final String INIT_SERVICE_CLEAR_BCB = "init.svc.clear-bcb";
+
     private static final int SOCKET_CONNECTION_MAX_RETRY = 30;
 
+    private static final Object sRequestLock = new Object();
+
     private Context mContext;
 
     public RecoverySystemService(Context context) {
@@ -69,95 +77,155 @@
         public boolean uncrypt(String filename, IRecoverySystemProgressListener listener) {
             if (DEBUG) Slog.d(TAG, "uncrypt: " + filename);
 
-            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
+            synchronized (sRequestLock) {
+                mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
 
-            // Write the filename into UNCRYPT_PACKAGE_FILE to be read by
-            // uncrypt.
-            RecoverySystem.UNCRYPT_PACKAGE_FILE.delete();
-
-            try (FileWriter uncryptFile = new FileWriter(RecoverySystem.UNCRYPT_PACKAGE_FILE)) {
-                uncryptFile.write(filename + "\n");
-            } catch (IOException e) {
-                Slog.e(TAG, "IOException when writing \"" + RecoverySystem.UNCRYPT_PACKAGE_FILE +
-                        "\": ", e);
-                return false;
-            }
-
-            // Trigger uncrypt via init.
-            SystemProperties.set("ctl.start", "uncrypt");
-
-            // Connect to the uncrypt service socket.
-            LocalSocket socket = connectService();
-            if (socket == null) {
-                Slog.e(TAG, "Failed to connect to uncrypt socket");
-                return false;
-            }
-
-            // Read the status from the socket.
-            DataInputStream dis = null;
-            DataOutputStream dos = null;
-            try {
-                dis = new DataInputStream(socket.getInputStream());
-                dos = new DataOutputStream(socket.getOutputStream());
-                int lastStatus = Integer.MIN_VALUE;
-                while (true) {
-                    int status = dis.readInt();
-                    // Avoid flooding the log with the same message.
-                    if (status == lastStatus && lastStatus != Integer.MIN_VALUE) {
-                        continue;
-                    }
-                    lastStatus = status;
-
-                    if (status >= 0 && status <= 100) {
-                        // Update status
-                        Slog.i(TAG, "uncrypt read status: " + status);
-                        if (listener != null) {
-                            try {
-                                listener.onProgress(status);
-                            } catch (RemoteException ignored) {
-                                Slog.w(TAG, "RemoteException when posting progress");
-                            }
-                        }
-                        if (status == 100) {
-                            Slog.i(TAG, "uncrypt successfully finished.");
-                            // Ack receipt of the final status code. uncrypt
-                            // waits for the ack so the socket won't be
-                            // destroyed before we receive the code.
-                            dos.writeInt(0);
-                            break;
-                        }
-                    } else {
-                        // Error in /system/bin/uncrypt.
-                        Slog.e(TAG, "uncrypt failed with status: " + status);
-                        // Ack receipt of the final status code. uncrypt waits
-                        // for the ack so the socket won't be destroyed before
-                        // we receive the code.
-                        dos.writeInt(0);
-                        return false;
-                    }
+                final boolean available = checkAndWaitForUncryptService();
+                if (!available) {
+                    Slog.e(TAG, "uncrypt service is unavailable.");
+                    return false;
                 }
-            } catch (IOException e) {
-                Slog.e(TAG, "IOException when reading status: ", e);
-                return false;
-            } finally {
-                IoUtils.closeQuietly(dis);
-                IoUtils.closeQuietly(dos);
-                IoUtils.closeQuietly(socket);
-            }
 
-            return true;
+                // Write the filename into UNCRYPT_PACKAGE_FILE to be read by
+                // uncrypt.
+                RecoverySystem.UNCRYPT_PACKAGE_FILE.delete();
+
+                try (FileWriter uncryptFile = new FileWriter(RecoverySystem.UNCRYPT_PACKAGE_FILE)) {
+                    uncryptFile.write(filename + "\n");
+                } catch (IOException e) {
+                    Slog.e(TAG, "IOException when writing \"" +
+                            RecoverySystem.UNCRYPT_PACKAGE_FILE + "\":", e);
+                    return false;
+                }
+
+                // Trigger uncrypt via init.
+                SystemProperties.set("ctl.start", "uncrypt");
+
+                // Connect to the uncrypt service socket.
+                LocalSocket socket = connectService();
+                if (socket == null) {
+                    Slog.e(TAG, "Failed to connect to uncrypt socket");
+                    return false;
+                }
+
+                // Read the status from the socket.
+                DataInputStream dis = null;
+                DataOutputStream dos = null;
+                try {
+                    dis = new DataInputStream(socket.getInputStream());
+                    dos = new DataOutputStream(socket.getOutputStream());
+                    int lastStatus = Integer.MIN_VALUE;
+                    while (true) {
+                        int status = dis.readInt();
+                        // Avoid flooding the log with the same message.
+                        if (status == lastStatus && lastStatus != Integer.MIN_VALUE) {
+                            continue;
+                        }
+                        lastStatus = status;
+
+                        if (status >= 0 && status <= 100) {
+                            // Update status
+                            Slog.i(TAG, "uncrypt read status: " + status);
+                            if (listener != null) {
+                                try {
+                                    listener.onProgress(status);
+                                } catch (RemoteException ignored) {
+                                    Slog.w(TAG, "RemoteException when posting progress");
+                                }
+                            }
+                            if (status == 100) {
+                                Slog.i(TAG, "uncrypt successfully finished.");
+                                // Ack receipt of the final status code. uncrypt
+                                // waits for the ack so the socket won't be
+                                // destroyed before we receive the code.
+                                dos.writeInt(0);
+                                break;
+                            }
+                        } else {
+                            // Error in /system/bin/uncrypt.
+                            Slog.e(TAG, "uncrypt failed with status: " + status);
+                            // Ack receipt of the final status code. uncrypt waits
+                            // for the ack so the socket won't be destroyed before
+                            // we receive the code.
+                            dos.writeInt(0);
+                            return false;
+                        }
+                    }
+                } catch (IOException e) {
+                    Slog.e(TAG, "IOException when reading status: ", e);
+                    return false;
+                } finally {
+                    IoUtils.closeQuietly(dis);
+                    IoUtils.closeQuietly(dos);
+                    IoUtils.closeQuietly(socket);
+                }
+
+                return true;
+            }
         }
 
         @Override // Binder call
         public boolean clearBcb() {
             if (DEBUG) Slog.d(TAG, "clearBcb");
-            return setupOrClearBcb(false, null);
+            synchronized (sRequestLock) {
+                return setupOrClearBcb(false, null);
+            }
         }
 
         @Override // Binder call
         public boolean setupBcb(String command) {
             if (DEBUG) Slog.d(TAG, "setupBcb: [" + command + "]");
-            return setupOrClearBcb(true, command);
+            synchronized (sRequestLock) {
+                return setupOrClearBcb(true, command);
+            }
+        }
+
+        @Override // Binder call
+        public void rebootRecoveryWithCommand(String command) {
+            if (DEBUG) Slog.d(TAG, "rebootRecoveryWithCommand: [" + command + "]");
+            synchronized (sRequestLock) {
+                if (!setupOrClearBcb(true, command)) {
+                    return;
+                }
+
+                // Having set up the BCB, go ahead and reboot.
+                PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+                pm.reboot(PowerManager.REBOOT_RECOVERY);
+            }
+        }
+
+        /**
+         * Check if any of the init services is still running. If so, we cannot
+         * start a new uncrypt/setup-bcb/clear-bcb service right away; otherwise
+         * it may break the socket communication since init creates / deletes
+         * the socket (/dev/socket/uncrypt) on service start / exit.
+         */
+        private boolean checkAndWaitForUncryptService() {
+            for (int retry = 0; retry < SOCKET_CONNECTION_MAX_RETRY; retry++) {
+                final String uncryptService = SystemProperties.get(INIT_SERVICE_UNCRYPT);
+                final String setupBcbService = SystemProperties.get(INIT_SERVICE_SETUP_BCB);
+                final String clearBcbService = SystemProperties.get(INIT_SERVICE_CLEAR_BCB);
+                final boolean busy = "running".equals(uncryptService) ||
+                        "running".equals(setupBcbService) || "running".equals(clearBcbService);
+                if (DEBUG) {
+                    Slog.i(TAG, "retry: " + retry + " busy: " + busy +
+                            " uncrypt: [" + uncryptService + "]" +
+                            " setupBcb: [" + setupBcbService + "]" +
+                            " clearBcb: [" + clearBcbService + "]");
+                }
+
+                if (!busy) {
+                    return true;
+                }
+
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    Slog.w(TAG, "Interrupted:", e);
+                }
+            }
+
+            return false;
         }
 
         private LocalSocket connectService() {
@@ -176,7 +244,7 @@
                     try {
                         Thread.sleep(1000);
                     } catch (InterruptedException e) {
-                        Slog.w(TAG, "Interrupted: ", e);
+                        Slog.w(TAG, "Interrupted:", e);
                     }
                 }
             }
@@ -190,6 +258,12 @@
         private boolean setupOrClearBcb(boolean isSetup, String command) {
             mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
 
+            final boolean available = checkAndWaitForUncryptService();
+            if (!available) {
+                Slog.e(TAG, "uncrypt service is unavailable.");
+                return false;
+            }
+
             if (isSetup) {
                 SystemProperties.set("ctl.start", "setup-bcb");
             } else {
@@ -232,7 +306,7 @@
                     return false;
                 }
             } catch (IOException e) {
-                Slog.e(TAG, "IOException when communicating with uncrypt: ", e);
+                Slog.e(TAG, "IOException when communicating with uncrypt:", e);
                 return false;
             } finally {
                 IoUtils.closeQuietly(dis);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 36d9697..afd451d 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1033,7 +1033,7 @@
             mDtDy = tmpFloats[Matrix.MSCALE_Y];
             float x = tmpFloats[Matrix.MTRANS_X];
             float y = tmpFloats[Matrix.MTRANS_Y];
-            mWin.mShownPosition.set((int) x, (int) y);
+            mWin.mShownPosition.set(Math.round(x), Math.round(y));
 
             // Now set the alpha...  but because our current hardware
             // can't do alpha transformation on a non-opaque surface,
@@ -1129,7 +1129,7 @@
             mDtDy = tmpFloats[Matrix.MSCALE_Y];
             float x = tmpFloats[Matrix.MTRANS_X];
             float y = tmpFloats[Matrix.MTRANS_Y];
-            mWin.mShownPosition.set((int) x, (int) y);
+            mWin.mShownPosition.set(Math.round(x), Math.round(y));
 
             mShownAlpha = mAlpha;
         } else {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 3fc945a..17f0da0 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -182,6 +182,14 @@
     public static final String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
 
     /**
+     * Since the default voicemail number is empty, if a SIM card does not have a voicemail number
+     * available the user cannot use voicemail. This flag allows the user to edit the voicemail
+     * number in such cases, and is false by default.
+     * @hide
+     */
+    public static final String KEY_EDITABLE_VOICEMAIL_NUMBER_BOOL= "editable_voicemail_number_bool";
+
+    /**
      * Determine whether the voicemail notification is persistent in the notification bar. If true,
      * the voicemail notifications cannot be dismissed from the notification bar.
      */
@@ -792,6 +800,7 @@
         sDefaults.putBoolean(KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL, false);
         sDefaults.putBoolean(KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL, true);
         sDefaults.putBoolean(KEY_USE_HFA_FOR_PROVISIONING_BOOL, false);
+        sDefaults.putBoolean(KEY_EDITABLE_VOICEMAIL_NUMBER_BOOL, false);
         sDefaults.putBoolean(KEY_USE_OTASP_FOR_PROVISIONING_BOOL, false);
         sDefaults.putBoolean(KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL, false);
         sDefaults.putBoolean(KEY_VOICE_PRIVACY_DISABLE_UI_BOOL, false);
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 67cf107..465addf 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -139,12 +139,6 @@
     public long seen;
 
     /**
-     * If the scan result is a valid autojoin candidate
-     * {@hide}
-     */
-    public int isAutoJoinCandidate;
-
-    /**
      * @hide
      * Update RSSI of the scan result
      * @param previousRssi
@@ -452,7 +446,6 @@
             numConnection = source.numConnection;
             numUsage = source.numUsage;
             numIpConfigFailures = source.numIpConfigFailures;
-            isAutoJoinCandidate = source.isAutoJoinCandidate;
             venueName = source.venueName;
             operatorFriendlyName = source.operatorFriendlyName;
             flags = source.flags;
@@ -530,7 +523,6 @@
         dest.writeInt(numConnection);
         dest.writeInt(numUsage);
         dest.writeInt(numIpConfigFailures);
-        dest.writeInt(isAutoJoinCandidate);
         dest.writeString((venueName != null) ? venueName.toString() : "");
         dest.writeString((operatorFriendlyName != null) ? operatorFriendlyName.toString() : "");
         dest.writeLong(this.flags);
@@ -600,7 +592,6 @@
                 sr.numConnection = in.readInt();
                 sr.numUsage = in.readInt();
                 sr.numIpConfigFailures = in.readInt();
-                sr.isAutoJoinCandidate = in.readInt();
                 sr.venueName = in.readString();
                 sr.operatorFriendlyName = in.readString();
                 sr.flags = in.readLong();
diff --git a/wifi/java/android/net/wifi/nan/IWifiNanManager.aidl b/wifi/java/android/net/wifi/nan/IWifiNanManager.aidl
index 56baba9..5485824 100644
--- a/wifi/java/android/net/wifi/nan/IWifiNanManager.aidl
+++ b/wifi/java/android/net/wifi/nan/IWifiNanManager.aidl
@@ -23,6 +23,7 @@
 import android.net.wifi.nan.IWifiNanEventCallback;
 import android.net.wifi.nan.PublishConfig;
 import android.net.wifi.nan.SubscribeConfig;
+import android.net.wifi.nan.WifiNanCharacteristics;
 import android.net.wifi.RttManager;
 
 /**
@@ -36,6 +37,7 @@
     void enableUsage();
     void disableUsage();
     boolean isUsageEnabled();
+    WifiNanCharacteristics getCharacteristics();
 
     // client API
     void connect(in IBinder binder, in String callingPackage, in IWifiNanEventCallback callback,
diff --git a/wifi/java/android/net/wifi/nan/PublishConfig.java b/wifi/java/android/net/wifi/nan/PublishConfig.java
index 4b67f9a..30c5bc0 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.java
+++ b/wifi/java/android/net/wifi/nan/PublishConfig.java
@@ -182,7 +182,7 @@
      *
      * @hide
      */
-    public void validate() throws IllegalArgumentException {
+    public void assertValid(WifiNanCharacteristics characteristics) throws IllegalArgumentException {
         WifiNanUtils.validateServiceName(mServiceName);
 
         if (!LvBufferUtils.isValid(mMatchFilter, 1)) {
@@ -198,6 +198,26 @@
         if (mTtlSec < 0) {
             throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
         }
+
+        if (characteristics != null) {
+            int maxServiceNameLength = characteristics.getMaxServiceNameLength();
+            if (maxServiceNameLength != 0 && mServiceName.length > maxServiceNameLength) {
+                throw new IllegalArgumentException(
+                        "Service name longer than supported by device characteristics");
+            }
+            int maxServiceSpecificInfoLength = characteristics.getMaxServiceSpecificInfoLength();
+            if (maxServiceSpecificInfoLength != 0 && mServiceSpecificInfo != null
+                    && mServiceSpecificInfo.length > maxServiceSpecificInfoLength) {
+                throw new IllegalArgumentException(
+                        "Service specific info longer than supported by device characteristics");
+            }
+            int maxMatchFilterLength = characteristics.getMaxMatchFilterLength();
+            if (maxMatchFilterLength != 0 && mMatchFilter != null
+                    && mMatchFilter.length > maxMatchFilterLength) {
+                throw new IllegalArgumentException(
+                        "Match filter longer than supported by device characteristics");
+            }
+        }
     }
 
     /**
diff --git a/wifi/java/android/net/wifi/nan/SubscribeConfig.java b/wifi/java/android/net/wifi/nan/SubscribeConfig.java
index 4352fcf..ea7b8e4 100644
--- a/wifi/java/android/net/wifi/nan/SubscribeConfig.java
+++ b/wifi/java/android/net/wifi/nan/SubscribeConfig.java
@@ -209,7 +209,7 @@
      *
      * @hide
      */
-    public void validate() throws IllegalArgumentException {
+    public void assertValid(WifiNanCharacteristics characteristics) throws IllegalArgumentException {
         WifiNanUtils.validateServiceName(mServiceName);
 
         if (!LvBufferUtils.isValid(mMatchFilter, 1)) {
@@ -229,6 +229,26 @@
             throw new IllegalArgumentException(
                     "Invalid matchType - must be MATCH_FIRST_ONLY or MATCH_ALL");
         }
+
+        if (characteristics != null) {
+            int maxServiceNameLength = characteristics.getMaxServiceNameLength();
+            if (maxServiceNameLength != 0 && mServiceName.length > maxServiceNameLength) {
+                throw new IllegalArgumentException(
+                        "Service name longer than supported by device characteristics");
+            }
+            int maxServiceSpecificInfoLength = characteristics.getMaxServiceSpecificInfoLength();
+            if (maxServiceSpecificInfoLength != 0 && mServiceSpecificInfo != null
+                    && mServiceSpecificInfo.length > maxServiceSpecificInfoLength) {
+                throw new IllegalArgumentException(
+                        "Service specific info longer than supported by device characteristics");
+            }
+            int maxMatchFilterLength = characteristics.getMaxMatchFilterLength();
+            if (maxMatchFilterLength != 0 && mMatchFilter != null
+                    && mMatchFilter.length > maxMatchFilterLength) {
+                throw new IllegalArgumentException(
+                        "Match filter longer than supported by device characteristics");
+            }
+        }
     }
 
     /**
diff --git a/wifi/java/android/net/wifi/nan/WifiNanCharacteristics.aidl b/wifi/java/android/net/wifi/nan/WifiNanCharacteristics.aidl
new file mode 100644
index 0000000..e562a00
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/WifiNanCharacteristics.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nan;
+
+parcelable WifiNanCharacteristics;
diff --git a/wifi/java/android/net/wifi/nan/WifiNanCharacteristics.java b/wifi/java/android/net/wifi/nan/WifiNanCharacteristics.java
new file mode 100644
index 0000000..f43ed4d
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/WifiNanCharacteristics.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nan;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * The characteristics of the Wi-Fi NAN implementation.
+ *
+ * @hide PROPOSED_NAN_API
+ */
+public class WifiNanCharacteristics implements Parcelable {
+    /** @hide */
+    public static final String KEY_MAX_SERVICE_NAME_LENGTH = "key_max_service_name_length";
+    /** @hide */
+    public static final String KEY_MAX_SERVICE_SPECIFIC_INFO_LENGTH =
+            "key_max_service_specific_info_length";
+    /** @hide */
+    public static final String KEY_MAX_MATCH_FILTER_LENGTH = "key_max_match_filter_length";
+
+    private Bundle mCharacteristics = new Bundle();
+
+    /** @hide : should not be created by apps */
+    public WifiNanCharacteristics(Bundle characteristics) {
+        mCharacteristics = characteristics;
+    }
+
+    /**
+     * Returns the maximum string length that can be used to specify a NAN service name. Restricts
+     * the parameters of the {@link PublishConfig.Builder#setServiceName(String)} and
+     * {@link SubscribeConfig.Builder#setServiceName(String)}.
+     *
+     * @return A positive integer, maximum string length of NAN service name.
+     */
+    public int getMaxServiceNameLength() {
+        return mCharacteristics.getInt(KEY_MAX_SERVICE_NAME_LENGTH);
+    }
+
+    /**
+     * Returns the maximum length of byte array that can be used to specify a NAN service specific
+     * information field: the arbitrary load used in discovery or the message length of NAN
+     * message exchange. Restricts the parameters of the
+     * {@link PublishConfig.Builder#setServiceSpecificInfo(byte[])},
+     * {@link SubscribeConfig.Builder#setServiceSpecificInfo(byte[])}, and
+     * {@link WifiNanDiscoveryBaseSession#sendMessage(Object, int, byte[])} variants.
+     *
+     * @return A positive integer, maximum length of byte array for NAN messaging.
+     */
+    public int getMaxServiceSpecificInfoLength() {
+        return mCharacteristics.getInt(KEY_MAX_SERVICE_SPECIFIC_INFO_LENGTH);
+    }
+
+    /**
+     * Returns the maximum length of byte array that can be used to specify a NAN match filter.
+     * Restricts the parameters of the {@link PublishConfig.Builder#setMatchFilter(byte[])} and
+     * {@link SubscribeConfig.Builder#setMatchFilter(byte[])}.
+     *
+     * @return A positive integer, maximum legngth of byte array for NAN discovery match filter.
+     */
+    public int getMaxMatchFilterLength() {
+        return mCharacteristics.getInt(KEY_MAX_MATCH_FILTER_LENGTH);
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeBundle(mCharacteristics);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Creator<WifiNanCharacteristics> CREATOR =
+            new Creator<WifiNanCharacteristics>() {
+                @Override
+                public WifiNanCharacteristics createFromParcel(Parcel in) {
+                    WifiNanCharacteristics c = new WifiNanCharacteristics(in.readBundle());
+                    return c;
+                }
+
+                @Override
+                public WifiNanCharacteristics[] newArray(int size) {
+                    return new WifiNanCharacteristics[size];
+                }
+            };
+}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanManager.java b/wifi/java/android/net/wifi/nan/WifiNanManager.java
index 705ba4a..002b953 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanManager.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanManager.java
@@ -201,6 +201,8 @@
      * Use the {@link #isAvailable()} to query the current status.
      * This broadcast is <b>not</b> sticky, use the {@link #isAvailable()} API after registering
      * the broadcast to check the current state of Wi-Fi NAN.
+     * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
+     * components will be launched.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_WIFI_NAN_STATE_CHANGED =
@@ -291,6 +293,20 @@
     }
 
     /**
+     * Returns the characteristics of the Wi-Fi NAN interface: a set of parameters which specify
+     * limitations on configurations, e.g. the maximum service name length.
+     *
+     * @return An object specifying configuration limitations of NAN.
+     */
+    public WifiNanCharacteristics getCharacteristics() {
+        try {
+            return mService.getCharacteristics();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Attach to the Wi-Fi NAN service - enabling the application to create discovery sessions or
      * create connections to peers. The device will attach to an existing cluster if it can find
      * one or create a new cluster (if it is the first to enable NAN in its vicinity). Results
diff --git a/wifi/java/android/net/wifi/nan/WifiNanSession.java b/wifi/java/android/net/wifi/nan/WifiNanSession.java
index 5fb2c06..df5e3c1 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanSession.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanSession.java
@@ -113,6 +113,8 @@
      *      An application must use the {@link WifiNanDiscoveryBaseSession#destroy()} to
      *      terminate the publish discovery session once it isn't needed. This will free
      *      resources as well terminate any on-air transmissions.
+     * <p>The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
+     * permission to start a publish discovery session.
      *
      * @param handler The Handler on whose thread to execute the callbacks of the {@code
      * callback} object. If a null is provided then the application's main thread will be used.
@@ -156,6 +158,8 @@
      *      An application must use the {@link WifiNanDiscoveryBaseSession#destroy()} to
      *      terminate the subscribe discovery session once it isn't needed. This will free
      *      resources as well terminate any on-air transmissions.
+     * <p>The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
+     * permission to start a subscribe discovery session.
      *
      * @param handler The Handler on whose thread to execute the callbacks of the {@code
      * callback} object. If a null is provided then the application's main thread will be used.