Merge "Use the application's usesCleartextTraffic flag"
diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java
index 413c369..ddb2d46 100644
--- a/core/java/android/app/ApplicationLoaders.java
+++ b/core/java/android/app/ApplicationLoaders.java
@@ -27,7 +27,8 @@
         return gApplicationLoaders;
     }
 
-    public ClassLoader getClassLoader(String zip, String libPath, ClassLoader parent)
+    public ClassLoader getClassLoader(String zip, String librarySearchPath,
+                                      String libraryPermittedPath, ClassLoader parent)
     {
         /*
          * This is the parent we use if they pass "null" in.  In theory
@@ -55,7 +56,7 @@
     
                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, zip);
                 PathClassLoader pathClassloader =
-                    new PathClassLoader(zip, libPath, parent);
+                    new PathClassLoader(zip, librarySearchPath, libraryPermittedPath, parent);
                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
                 mLoaders.put(zip, pathClassloader);
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index c2bf28a..0120922 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -359,7 +359,15 @@
                     }
                 }
 
-                final String lib = TextUtils.join(File.pathSeparator, libPaths);
+                if (mApplicationInfo.isSystemApp()) {
+                    // Add path to system libraries to libPaths;
+                    // Access to system libs should be limited
+                    // to bundled applications; this is why updated
+                    // system apps are not included.
+                    libPaths.add(System.getProperty("java.library.path"));
+                }
+
+                final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
 
                 /*
                  * With all the combination done (if necessary, actually
@@ -367,14 +375,17 @@
                  */
 
                 if (ActivityThread.localLOGV)
-                    Slog.v(ActivityThread.TAG, "Class path: " + zip + ", JNI path: " + lib);
+                    Slog.v(ActivityThread.TAG, "Class path: " + zip +
+                            ", JNI path: " + librarySearchPath);
 
                 // Temporarily disable logging of disk reads on the Looper thread
                 // as this is early and necessary.
                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
 
-                mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip, lib,
-                        mBaseClassLoader);
+                String libraryPermittedPath = mAppDir + File.pathSeparator + mDataDir;
+
+                mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip, librarySearchPath,
+                        libraryPermittedPath, mBaseClassLoader);
 
                 StrictMode.setThreadPolicy(oldPolicy);
             } else {
diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java
index 2e05edb..dcf1c80 100644
--- a/core/java/android/app/NativeActivity.java
+++ b/core/java/android/app/NativeActivity.java
@@ -35,6 +35,8 @@
 import android.view.WindowManager;
 import android.view.inputmethod.InputMethodManager;
 
+import dalvik.system.BaseDexClassLoader;
+
 import java.io.File;
 
 /**
@@ -93,7 +95,9 @@
     
     private native long loadNativeCode(String path, String funcname, MessageQueue queue,
             String internalDataPath, String obbPath, String externalDataPath, int sdkVersion,
-            AssetManager assetMgr, byte[] savedState);
+            AssetManager assetMgr, byte[] savedState, ClassLoader classLoader, String libraryPath,
+            String isolationPath);
+    private native String getDlError();
     private native void unloadNativeCode(long handle);
     private native void onStartNative(long handle);
     private native void onResumeNative(long handle);
@@ -157,15 +161,10 @@
         } catch (PackageManager.NameNotFoundException e) {
             throw new RuntimeException("Error getting activity info", e);
         }
-        
-        String path = null;
-        
-        File libraryFile = new File(ai.applicationInfo.nativeLibraryDir,
-                System.mapLibraryName(libname));
-        if (libraryFile.exists()) {
-            path = libraryFile.getPath();
-        }
-        
+
+        BaseDexClassLoader classLoader = (BaseDexClassLoader) getClassLoader();
+        String path = classLoader.findLibrary(libname);
+
         if (path == null) {
             throw new IllegalArgumentException("Unable to find native library: " + libname);
         }
@@ -176,10 +175,13 @@
         mNativeHandle = loadNativeCode(path, funcname, Looper.myQueue(),
                 getAbsolutePath(getFilesDir()), getAbsolutePath(getObbDir()),
                 getAbsolutePath(getExternalFilesDir(null)),
-                Build.VERSION.SDK_INT, getAssets(), nativeSavedState);
+                Build.VERSION.SDK_INT, getAssets(), nativeSavedState,
+                classLoader, classLoader.getLdLibraryPath(),
+                classLoader.getLibraryPermittedPath());
 
         if (mNativeHandle == 0) {
-            throw new IllegalArgumentException("Unable to load native library: " + path);
+            throw new UnsatisfiedLinkError(
+                    "Unable to load native library \"" + path + "\": " + getDlError());
         }
         super.onCreate(savedInstanceState);
     }
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 1fc69c0..e884c02 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -47,6 +47,8 @@
 import java.util.LinkedHashMap;
 import java.util.List;
 
+import static android.system.OsConstants.*;
+
 /**
  * The Camera class is used to set image capture settings, start/stop preview,
  * snap pictures, and retrieve frames for encoding for video.  This class is a
@@ -173,13 +175,6 @@
     private final Object mAutoFocusCallbackLock = new Object();
 
     private static final int NO_ERROR = 0;
-    private static final int EACCESS = -13;
-    private static final int ENODEV = -19;
-    private static final int EBUSY = -16;
-    private static final int EINVAL = -22;
-    private static final int ENOSYS = -38;
-    private static final int EUSERS = -87;
-    private static final int EOPNOTSUPP = -95;
 
     /**
      * Broadcast Action:  A new picture is taken by the camera, and the entry of
@@ -415,30 +410,28 @@
     private Camera(int cameraId, int halVersion) {
         int err = cameraInitVersion(cameraId, halVersion);
         if (checkInitErrors(err)) {
-            switch(err) {
-                case EACCESS:
-                    throw new RuntimeException("Fail to connect to camera service");
-                case ENODEV:
-                    throw new RuntimeException("Camera initialization failed");
-                case ENOSYS:
-                    throw new RuntimeException("Camera initialization failed because some methods"
-                            + " are not implemented");
-                case EOPNOTSUPP:
-                    throw new RuntimeException("Camera initialization failed because the hal"
-                            + " version is not supported by this device");
-                case EINVAL:
-                    throw new RuntimeException("Camera initialization failed because the input"
-                            + " arugments are invalid");
-                case EBUSY:
-                    throw new RuntimeException("Camera initialization failed because the camera"
-                            + " device was already opened");
-                case EUSERS:
-                    throw new RuntimeException("Camera initialization failed because the max"
-                            + " number of camera devices were already opened");
-                default:
-                    // Should never hit this.
-                    throw new RuntimeException("Unknown camera error");
+            if (err == -EACCES) {
+                throw new RuntimeException("Fail to connect to camera service");
+            } else if (err == -ENODEV) {
+                throw new RuntimeException("Camera initialization failed");
+            } else if (err == -ENOSYS) {
+                throw new RuntimeException("Camera initialization failed because some methods"
+                        + " are not implemented");
+            } else if (err == -EOPNOTSUPP) {
+                throw new RuntimeException("Camera initialization failed because the hal"
+                        + " version is not supported by this device");
+            } else if (err == -EINVAL) {
+                throw new RuntimeException("Camera initialization failed because the input"
+                        + " arugments are invalid");
+            } else if (err == -EBUSY) {
+                throw new RuntimeException("Camera initialization failed because the camera"
+                        + " device was already opened");
+            } else if (err == -EUSERS) {
+                throw new RuntimeException("Camera initialization failed because the max"
+                        + " number of camera devices were already opened");
             }
+            // Should never hit this.
+            throw new RuntimeException("Unknown camera error");
         }
     }
 
@@ -490,15 +483,13 @@
     Camera(int cameraId) {
         int err = cameraInitNormal(cameraId);
         if (checkInitErrors(err)) {
-            switch(err) {
-                case EACCESS:
-                    throw new RuntimeException("Fail to connect to camera service");
-                case ENODEV:
-                    throw new RuntimeException("Camera initialization failed");
-                default:
-                    // Should never hit this.
-                    throw new RuntimeException("Unknown camera error");
+            if (err == -EACCES) {
+                throw new RuntimeException("Fail to connect to camera service");
+            } else if (err == -ENODEV) {
+                throw new RuntimeException("Camera initialization failed");
             }
+            // Should never hit this.
+            throw new RuntimeException("Unknown camera error");
         }
     }
 
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
index 6b8e113..798c941 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
@@ -43,6 +43,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static android.system.OsConstants.EACCES;
+import static android.system.OsConstants.ENODEV;
+
 /**
  * Compatibility implementation of the Camera2 API binder interface.
  *
@@ -88,6 +91,14 @@
         mSurfaceIdCounter = 0;
     }
 
+    private static int translateErrorsFromCamera1(int errorCode) {
+        if (errorCode == -EACCES) {
+            return CameraBinderDecorator.PERMISSION_DENIED;
+        }
+
+        return errorCode;
+    }
+
     /**
      * Create a separate looper/thread for the camera to run on; open the camera.
      *
@@ -382,7 +393,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot submit request, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         synchronized(mConfigureLock) {
@@ -402,7 +413,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot submit request list, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         synchronized(mConfigureLock) {
@@ -421,7 +432,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot cancel request, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         synchronized(mConfigureLock) {
@@ -442,7 +453,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot begin configure, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         synchronized(mConfigureLock) {
@@ -462,7 +473,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot end configure, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         ArrayList<Surface> surfaces = null;
@@ -490,7 +501,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot delete stream, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         synchronized(mConfigureLock) {
@@ -515,7 +526,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot create stream, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         synchronized(mConfigureLock) {
@@ -552,7 +563,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot create default request, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         CameraMetadataNative template;
@@ -585,7 +596,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot wait until idle, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         synchronized(mConfigureLock) {
@@ -605,7 +616,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot flush, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         synchronized(mConfigureLock) {
@@ -627,7 +638,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot prepare stream, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         // LEGACY doesn't support actual prepare, just signal success right away
@@ -647,7 +658,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot tear down stream, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         // LEGACY doesn't support actual teardown, so just a no-op
diff --git a/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java b/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java
index 4b7cfbf..4501e81 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java
@@ -19,6 +19,8 @@
 import android.hardware.camera2.utils.CameraBinderDecorator;
 import android.util.AndroidException;
 
+import static android.system.OsConstants.ENODEV;
+
 /**
  * Utility class containing exception handling used solely by the compatibility mode shim.
  */
@@ -51,18 +53,15 @@
      * exceptions.</p>
      *
      * @param errorFlag error to throw as an exception.
-     * @throws {@link BufferQueueAbandonedException} for {@link CameraBinderDecorator#ENODEV}.
+     * @throws {@link BufferQueueAbandonedException} for -ENODEV.
      * @throws {@link UnsupportedOperationException} for an unknown negative error code.
      * @return {@code errorFlag} if the value was non-negative, throws otherwise.
      */
     public static int throwOnError(int errorFlag) throws BufferQueueAbandonedException {
-        switch (errorFlag) {
-            case CameraBinderDecorator.NO_ERROR: {
-                return CameraBinderDecorator.NO_ERROR;
-            }
-            case CameraBinderDecorator.BAD_VALUE: {
-                throw new BufferQueueAbandonedException();
-            }
+        if (errorFlag == CameraBinderDecorator.NO_ERROR) {
+            return CameraBinderDecorator.NO_ERROR;
+        } else if (errorFlag == -ENODEV) {
+            throw new BufferQueueAbandonedException();
         }
 
         if (errorFlag < 0) {
diff --git a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
index 1aee794..162edc9 100644
--- a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
+++ b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
@@ -22,6 +22,7 @@
 import static android.hardware.camera2.CameraAccessException.CAMERA_ERROR;
 import static android.hardware.camera2.CameraAccessException.MAX_CAMERAS_IN_USE;
 import static android.hardware.camera2.CameraAccessException.CAMERA_DEPRECATED_HAL;
+import static android.system.OsConstants.*;
 
 import android.os.DeadObjectException;
 import android.os.RemoteException;
@@ -37,12 +38,12 @@
 public class CameraBinderDecorator {
 
     public static final int NO_ERROR = 0;
-    public static final int PERMISSION_DENIED = -1;
-    public static final int ALREADY_EXISTS = -17;
-    public static final int BAD_VALUE = -22;
-    public static final int DEAD_OBJECT = -32;
-    public static final int INVALID_OPERATION = -38;
-    public static final int TIMED_OUT = -110;
+    public static final int PERMISSION_DENIED = -EPERM;
+    public static final int ALREADY_EXISTS = -EEXIST;
+    public static final int BAD_VALUE = -EINVAL;
+    public static final int DEAD_OBJECT = -ENOSYS;
+    public static final int INVALID_OPERATION = -EPIPE;
+    public static final int TIMED_OUT = -ETIMEDOUT;
 
     /**
      * TODO: add as error codes in Errors.h
@@ -52,12 +53,6 @@
      * - NOT_SUPPORTED
      * - TOO_MANY_USERS
      */
-    public static final int EACCES = -13;
-    public static final int EBUSY = -16;
-    public static final int ENODEV = -19;
-    public static final int EOPNOTSUPP = -95;
-    public static final int EUSERS = -87;
-
 
     static class CameraBinderDecoratorListener implements Decorator.DecoratorListener {
 
@@ -101,35 +96,34 @@
      * @param errorFlag error to throw as an exception.
      */
     public static void throwOnError(int errorFlag) {
-        switch (errorFlag) {
-            case NO_ERROR:
-                return;
-            case PERMISSION_DENIED:
-                throw new SecurityException("Lacking privileges to access camera service");
-            case ALREADY_EXISTS:
-                // This should be handled at the call site. Typically this isn't bad,
-                // just means we tried to do an operation that already completed.
-                return;
-            case BAD_VALUE:
-                throw new IllegalArgumentException("Bad argument passed to camera service");
-            case DEAD_OBJECT:
-                throw new CameraRuntimeException(CAMERA_DISCONNECTED);
-            case TIMED_OUT:
-                throw new CameraRuntimeException(CAMERA_ERROR,
-                        "Operation timed out in camera service");
-            case EACCES:
-                throw new CameraRuntimeException(CAMERA_DISABLED);
-            case EBUSY:
-                throw new CameraRuntimeException(CAMERA_IN_USE);
-            case EUSERS:
-                throw new CameraRuntimeException(MAX_CAMERAS_IN_USE);
-            case ENODEV:
-                throw new CameraRuntimeException(CAMERA_DISCONNECTED);
-            case EOPNOTSUPP:
-                throw new CameraRuntimeException(CAMERA_DEPRECATED_HAL);
-            case INVALID_OPERATION:
-                throw new CameraRuntimeException(CAMERA_ERROR,
-                        "Illegal state encountered in camera service.");
+        if (errorFlag == NO_ERROR) {
+            return;
+        } else if (errorFlag == PERMISSION_DENIED) {
+            throw new SecurityException("Lacking privileges to access camera service");
+        } else if (errorFlag == ALREADY_EXISTS) {
+            // This should be handled at the call site. Typically this isn't bad,
+            // just means we tried to do an operation that already completed.
+            return;
+        } else if (errorFlag == BAD_VALUE) {
+            throw new IllegalArgumentException("Bad argument passed to camera service");
+        } else if (errorFlag == DEAD_OBJECT) {
+            throw new CameraRuntimeException(CAMERA_DISCONNECTED);
+        } else if (errorFlag == TIMED_OUT) {
+            throw new CameraRuntimeException(CAMERA_ERROR,
+                    "Operation timed out in camera service");
+        } else if (errorFlag == -EACCES) {
+            throw new CameraRuntimeException(CAMERA_DISABLED);
+        } else if (errorFlag == -EBUSY) {
+            throw new CameraRuntimeException(CAMERA_IN_USE);
+        } else if (errorFlag == -EUSERS) {
+            throw new CameraRuntimeException(MAX_CAMERAS_IN_USE);
+        } else if (errorFlag == -ENODEV) {
+            throw new CameraRuntimeException(CAMERA_DISCONNECTED);
+        } else if (errorFlag == -EOPNOTSUPP) {
+            throw new CameraRuntimeException(CAMERA_DEPRECATED_HAL);
+        } else if (errorFlag == INVALID_OPERATION) {
+            throw new CameraRuntimeException(CAMERA_ERROR,
+                    "Illegal state encountered in camera service.");
         }
 
         /**
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java
index c85e97b..d490409 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.java
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java
@@ -25,6 +25,8 @@
 import java.util.Arrays;
 import java.util.UUID;
 
+import static android.system.OsConstants.*;
+
 /**
  * The SoundTrigger class provides access via JNI to the native service managing
  * the sound trigger HAL.
@@ -35,11 +37,11 @@
 
     public static final int STATUS_OK = 0;
     public static final int STATUS_ERROR = Integer.MIN_VALUE;
-    public static final int STATUS_PERMISSION_DENIED = -1;
-    public static final int STATUS_NO_INIT = -19;
-    public static final int STATUS_BAD_VALUE = -22;
-    public static final int STATUS_DEAD_OBJECT = -32;
-    public static final int STATUS_INVALID_OPERATION = -38;
+    public static final int STATUS_PERMISSION_DENIED = -EPERM;
+    public static final int STATUS_NO_INIT = -ENODEV;
+    public static final int STATUS_BAD_VALUE = -EINVAL;
+    public static final int STATUS_DEAD_OBJECT = -EPIPE;
+    public static final int STATUS_INVALID_OPERATION = -ENOSYS;
 
     /*****************************************************************************
      * A ModuleProperties describes a given sound trigger hardware module
diff --git a/core/java/android/security/net/config/ApplicationConfig.java b/core/java/android/security/net/config/ApplicationConfig.java
index b627641..71d9d5d 100644
--- a/core/java/android/security/net/config/ApplicationConfig.java
+++ b/core/java/android/security/net/config/ApplicationConfig.java
@@ -68,7 +68,7 @@
      */
     public NetworkSecurityConfig getConfigForHostname(String hostname) {
         ensureInitialized();
-        if (hostname.isEmpty() || mConfigs == null) {
+        if (hostname == null || hostname.isEmpty() || mConfigs == null) {
             return mDefaultConfig;
         }
         if (hostname.charAt(0) ==  '.') {
diff --git a/core/java/android/security/net/config/CertificateSource.java b/core/java/android/security/net/config/CertificateSource.java
index 2b7829e..7e3601e 100644
--- a/core/java/android/security/net/config/CertificateSource.java
+++ b/core/java/android/security/net/config/CertificateSource.java
@@ -23,4 +23,5 @@
 public interface CertificateSource {
     Set<X509Certificate> getCertificates();
     X509Certificate findBySubjectAndPublicKey(X509Certificate cert);
+    X509Certificate findByIssuerAndSignature(X509Certificate cert);
 }
diff --git a/core/java/android/security/net/config/CertificatesEntryRef.java b/core/java/android/security/net/config/CertificatesEntryRef.java
index 1d15e19..ff728ef 100644
--- a/core/java/android/security/net/config/CertificatesEntryRef.java
+++ b/core/java/android/security/net/config/CertificatesEntryRef.java
@@ -51,4 +51,13 @@
 
         return new TrustAnchor(foundCert, mOverridesPins);
     }
+
+    public TrustAnchor findByIssuerAndSignature(X509Certificate cert) {
+        X509Certificate foundCert = mSource.findByIssuerAndSignature(cert);
+        if (foundCert == null) {
+            return null;
+        }
+
+        return new TrustAnchor(foundCert, mOverridesPins);
+    }
 }
diff --git a/core/java/android/security/net/config/DirectoryCertificateSource.java b/core/java/android/security/net/config/DirectoryCertificateSource.java
index 92c7092..bf88e58 100644
--- a/core/java/android/security/net/config/DirectoryCertificateSource.java
+++ b/core/java/android/security/net/config/DirectoryCertificateSource.java
@@ -94,6 +94,21 @@
         });
     }
 
+    @Override
+    public X509Certificate findByIssuerAndSignature(final X509Certificate cert) {
+        return findCert(cert.getIssuerX500Principal(), new CertSelector() {
+            @Override
+            public boolean match(X509Certificate ca) {
+                try {
+                    cert.verify(ca.getPublicKey());
+                    return true;
+                } catch (Exception e) {
+                    return false;
+                }
+            }
+        });
+    }
+
     private static interface CertSelector {
         boolean match(X509Certificate cert);
     }
diff --git a/core/java/android/security/net/config/KeyStoreCertificateSource.java b/core/java/android/security/net/config/KeyStoreCertificateSource.java
index 7a01a64..b6105cd 100644
--- a/core/java/android/security/net/config/KeyStoreCertificateSource.java
+++ b/core/java/android/security/net/config/KeyStoreCertificateSource.java
@@ -80,4 +80,14 @@
         }
         return anchor.getTrustedCert();
     }
+
+    @Override
+    public X509Certificate findByIssuerAndSignature(X509Certificate cert) {
+        ensureInitialized();
+        java.security.cert.TrustAnchor anchor = mIndex.findByIssuerAndSignature(cert);
+        if (anchor == null) {
+            return null;
+        }
+        return anchor.getTrustedCert();
+    }
 }
diff --git a/core/java/android/security/net/config/NetworkSecurityConfig.java b/core/java/android/security/net/config/NetworkSecurityConfig.java
index 2ab07b5..0a2edff 100644
--- a/core/java/android/security/net/config/NetworkSecurityConfig.java
+++ b/core/java/android/security/net/config/NetworkSecurityConfig.java
@@ -134,6 +134,17 @@
         return null;
     }
 
+    /** @hide */
+    public TrustAnchor findTrustAnchorByIssuerAndSignature(X509Certificate cert) {
+        for (CertificatesEntryRef ref : mCertificatesEntryRefs) {
+            TrustAnchor anchor = ref.findByIssuerAndSignature(cert);
+            if (anchor != null) {
+                return anchor;
+            }
+        }
+        return null;
+    }
+
     /**
      * Return a {@link Builder} for the default {@code NetworkSecurityConfig}.
      *
diff --git a/core/java/android/security/net/config/NetworkSecurityTrustManager.java b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
index 6013c1e..982ed68 100644
--- a/core/java/android/security/net/config/NetworkSecurityTrustManager.java
+++ b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
@@ -46,17 +46,13 @@
             throw new NullPointerException("config must not be null");
         }
         mNetworkSecurityConfig = config;
-        // TODO: Create our own better KeyStoreImpl
         try {
+            TrustedCertificateStoreAdapter certStore = new TrustedCertificateStoreAdapter(config);
+            // Provide an empty KeyStore since TrustManagerImpl doesn't support null KeyStores.
+            // TrustManagerImpl will use certStore to lookup certificates.
             KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
             store.load(null);
-            int certNum = 0;
-            for (TrustAnchor anchor : mNetworkSecurityConfig.getTrustAnchors()) {
-                store.setEntry(String.valueOf(certNum++),
-                        new KeyStore.TrustedCertificateEntry(anchor.certificate),
-                        null);
-            }
-            mDelegate = new TrustManagerImpl(store);
+            mDelegate = new TrustManagerImpl(store, null, certStore);
         } catch (GeneralSecurityException | IOException e) {
             throw new RuntimeException(e);
         }
diff --git a/core/java/android/security/net/config/ResourceCertificateSource.java b/core/java/android/security/net/config/ResourceCertificateSource.java
index b007f8f..e489c2c 100644
--- a/core/java/android/security/net/config/ResourceCertificateSource.java
+++ b/core/java/android/security/net/config/ResourceCertificateSource.java
@@ -90,4 +90,14 @@
         }
         return anchor.getTrustedCert();
     }
+
+    @Override
+    public X509Certificate findByIssuerAndSignature(X509Certificate cert) {
+        ensureInitialized();
+        java.security.cert.TrustAnchor anchor = mIndex.findByIssuerAndSignature(cert);
+        if (anchor == null) {
+            return null;
+        }
+        return anchor.getTrustedCert();
+    }
 }
diff --git a/core/java/android/security/net/config/RootTrustManager.java b/core/java/android/security/net/config/RootTrustManager.java
index e307ad0..b4e58e6 100644
--- a/core/java/android/security/net/config/RootTrustManager.java
+++ b/core/java/android/security/net/config/RootTrustManager.java
@@ -71,6 +71,10 @@
      */
     public List<X509Certificate> checkServerTrusted(X509Certificate[] certs, String authType,
             String hostname) throws CertificateException {
+        if (hostname == null && mConfig.hasPerDomainConfigs()) {
+            throw new CertificateException(
+                    "Domain specific configurations require that the hostname be provided");
+        }
         NetworkSecurityConfig config = mConfig.getConfigForHostname(hostname);
         return config.getTrustManager().checkServerTrusted(certs, authType, hostname);
     }
diff --git a/core/java/android/security/net/config/TrustedCertificateStoreAdapter.java b/core/java/android/security/net/config/TrustedCertificateStoreAdapter.java
new file mode 100644
index 0000000..4a90f82
--- /dev/null
+++ b/core/java/android/security/net/config/TrustedCertificateStoreAdapter.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2015 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.security.net.config;
+
+import java.io.File;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Set;
+
+import com.android.org.conscrypt.TrustedCertificateStore;
+
+/** @hide */
+public class TrustedCertificateStoreAdapter extends TrustedCertificateStore {
+    private final NetworkSecurityConfig mConfig;
+
+    public TrustedCertificateStoreAdapter(NetworkSecurityConfig config) {
+        mConfig = config;
+    }
+
+    @Override
+    public X509Certificate findIssuer(X509Certificate cert) {
+        TrustAnchor anchor = mConfig.findTrustAnchorByIssuerAndSignature(cert);
+        if (anchor == null) {
+            return null;
+        }
+        return anchor.certificate;
+    }
+
+    @Override
+    public X509Certificate getTrustAnchor(X509Certificate cert) {
+        TrustAnchor anchor = mConfig.findTrustAnchorBySubjectAndPublicKey(cert);
+        if (anchor == null) {
+            return null;
+        }
+        return anchor.certificate;
+    }
+
+    @Override
+    public boolean isUserAddedCertificate(X509Certificate cert) {
+        // isUserAddedCertificate is used only for pinning overrides, so use overridesPins here.
+        TrustAnchor anchor = mConfig.findTrustAnchorBySubjectAndPublicKey(cert);
+        if (anchor == null) {
+            return false;
+        }
+        return anchor.overridesPins;
+    }
+
+    @Override
+    public File getCertificateFile(File dir, X509Certificate x) {
+        // getCertificateFile is only used for tests, do not support it here.
+        throw new UnsupportedOperationException();
+    }
+
+    // The methods below are exposed in TrustedCertificateStore but not used by conscrypt, do not
+    // support them.
+
+    @Override
+    public Certificate getCertificate(String alias) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Certificate getCertificate(String alias, boolean includeDeletedSystem) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Date getCreationDate(String alias) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set<String> aliases() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set<String> userAliases() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set<String> allSystemAliases() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean containsAlias(String alias) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getCertificateAlias(Certificate c) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getCertificateAlias(Certificate c, boolean includeDeletedSystem) {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 4c68e01..8641292 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -251,7 +251,8 @@
     libminikin \
     libprocessgroup \
     libnativebridge \
-    libradio_metadata
+    libradio_metadata \
+    libnativeloader
 
 LOCAL_SHARED_LIBRARIES += \
     libhwui \
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 95be3f2..6ecb3fb 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -21,6 +21,8 @@
 #include <dlfcn.h>
 #include <fcntl.h>
 
+#include <memory>
+
 #include <android_runtime/android_app_NativeActivity.h>
 #include <android_runtime/android_util_AssetManager.h>
 #include <android_runtime/android_view_Surface.h>
@@ -39,6 +41,7 @@
 #include "android_view_KeyEvent.h"
 
 #include "nativebridge/native_bridge.h"
+#include "nativeloader/native_loader.h"
 
 #include "core_jni_helpers.h"
 
@@ -255,18 +258,19 @@
 static jlong
 loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName,
         jobject messageQueue, jstring internalDataDir, jstring obbDir,
-        jstring externalDataDir, jint sdkVersion,
-        jobject jAssetMgr, jbyteArray savedState)
-{
+        jstring externalDataDir, jint sdkVersion, jobject jAssetMgr,
+        jbyteArray savedState, jobject classLoader, jstring libraryPath,
+        jstring isolationPath) {
     if (kLogTrace) {
         ALOGD("loadNativeCode_native");
     }
 
     const char* pathStr = env->GetStringUTFChars(path, NULL);
-    NativeCode* code = NULL;
+    std::unique_ptr<NativeCode> code;
     bool needNativeBridge = false;
 
-    void* handle = dlopen(pathStr, RTLD_LAZY);
+    void* handle = OpenNativeLibrary(env, sdkVersion, pathStr, classLoader,
+                                     libraryPath, isolationPath);
     if (handle == NULL) {
         if (NativeBridgeIsSupported(pathStr)) {
             handle = NativeBridgeLoadLibrary(pathStr, RTLD_LAZY);
@@ -284,26 +288,23 @@
             funcPtr = dlsym(handle, funcStr);
         }
 
-        code = new NativeCode(handle, (ANativeActivity_createFunc*)funcPtr);
+        code.reset(new NativeCode(handle, (ANativeActivity_createFunc*)funcPtr));
         env->ReleaseStringUTFChars(funcName, funcStr);
 
         if (code->createActivityFunc == NULL) {
             ALOGW("ANativeActivity_onCreate not found");
-            delete code;
             return 0;
         }
         
         code->messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueue);
         if (code->messageQueue == NULL) {
             ALOGW("Unable to retrieve native MessageQueue");
-            delete code;
             return 0;
         }
         
         int msgpipe[2];
         if (pipe(msgpipe)) {
             ALOGW("could not create pipe: %s", strerror(errno));
-            delete code;
             return 0;
         }
         code->mainWorkRead = msgpipe[0];
@@ -315,12 +316,11 @@
         SLOGW_IF(result != 0, "Could not make main work write pipe "
                 "non-blocking: %s", strerror(errno));
         code->messageQueue->getLooper()->addFd(
-                code->mainWorkRead, 0, ALOOPER_EVENT_INPUT, mainWorkCallback, code);
+                code->mainWorkRead, 0, ALOOPER_EVENT_INPUT, mainWorkCallback, code.get());
         
         code->ANativeActivity::callbacks = &code->callbacks;
         if (env->GetJavaVM(&code->vm) < 0) {
             ALOGW("NativeActivity GetJavaVM failed");
-            delete code;
             return 0;
         }
         code->env = env;
@@ -356,14 +356,18 @@
             rawSavedSize = env->GetArrayLength(savedState);
         }
 
-        code->createActivityFunc(code, rawSavedState, rawSavedSize);
+        code->createActivityFunc(code.get(), rawSavedState, rawSavedSize);
 
         if (rawSavedState != NULL) {
             env->ReleaseByteArrayElements(savedState, rawSavedState, 0);
         }
     }
     
-    return (jlong)code;
+    return (jlong)code.release();
+}
+
+static jstring getDlError_native(JNIEnv* env, jobject clazz) {
+  return env->NewStringUTF(dlerror());
 }
 
 static void
@@ -651,8 +655,10 @@
 }
 
 static const JNINativeMethod g_methods[] = {
-    { "loadNativeCode", "(Ljava/lang/String;Ljava/lang/String;Landroid/os/MessageQueue;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILandroid/content/res/AssetManager;[B)J",
-            (void*)loadNativeCode_native },
+    { "loadNativeCode",
+        "(Ljava/lang/String;Ljava/lang/String;Landroid/os/MessageQueue;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILandroid/content/res/AssetManager;[BLjava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;)J",
+        (void*)loadNativeCode_native },
+    { "getDlError", "()Ljava/lang/String;", (void*) getDlError_native },
     { "unloadNativeCode", "(J)V", (void*)unloadNativeCode_native },
     { "onStartNative", "(J)V", (void*)onStart_native },
     { "onResumeNative", "(J)V", (void*)onResume_native },
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 09cceb6..afcb8f8 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -597,14 +597,14 @@
 
     <!-- Allows an application to access the IMS call service: making and
          modifying a call
-        <p>Protection level: signature|system
+        <p>Protection level: signature|privileged
         @hide
     -->
     <permission android:name="android.permission.ACCESS_IMS_CALL_SERVICE"
         android:permissionGroup="android.permission-group.PHONE"
         android:label="@string/permlab_accessImsCallService"
         android:description="@string/permdesc_accessImsCallService"
-        android:protectionLevel="signature|system" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to read the user's call log.
          <p class="note"><strong>Note:</strong> If your app uses the
@@ -871,7 +871,7 @@
     <!-- @SystemApi @hide Allows an application to modify cell broadcasts through the content provider.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.MODIFY_CELL_BROADCASTS"
-                android:protectionLevel="signature|system" />
+                android:protectionLevel="signature|privileged" />
 
     <!-- =============================================================== -->
     <!-- Permissions for setting the device alarm                        -->
@@ -892,16 +892,16 @@
     <eat-comment />
 
     <!-- Allows an application to modify and remove existing voicemails in the system
-        <p>Protection level: system|signature
+        <p>Protection level: signature|privileged
     -->
     <permission android:name="com.android.voicemail.permission.WRITE_VOICEMAIL"
-        android:protectionLevel="system|signature" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to read voicemails in the system.
-         <p>Protection level: system|signature
+         <p>Protection level: signature|privileged
     -->
     <permission android:name="com.android.voicemail.permission.READ_VOICEMAIL"
-        android:protectionLevel="system|signature" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- ======================================= -->
     <!-- Permissions for accessing location info -->
@@ -1037,7 +1037,7 @@
          allow or disallow phonebook access or message access.
          This is not available to third party applications. -->
     <permission android:name="android.permission.BLUETOOTH_PRIVILEGED"
-        android:protectionLevel="system|signature" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Control access to email providers exclusively for Bluetooth
          @hide
@@ -1275,26 +1275,26 @@
          corresponds to a device SIM.
          @hide -->
     <permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION"
-        android:protectionLevel="system|signature" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Protects the ability to register any PhoneAccount with
          PhoneAccount#CAPABILITY_CALL_PROVIDER.
          @hide -->
     <permission android:name="android.permission.REGISTER_CALL_PROVIDER"
-        android:protectionLevel="system|signature" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Protects the ability to register any PhoneAccount with
          PhoneAccount#CAPABILITY_CONNECTION_MANAGER
          @hide -->
     <permission android:name="android.permission.REGISTER_CONNECTION_MANAGER"
-        android:protectionLevel="system|signature" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by a {@link android.telecom.InCallService},
          to ensure that only the system can bind to it.
-         <p>Protection level: system|signature
+         <p>Protection level: signature|privileged
     -->
     <permission android:name="android.permission.BIND_INCALL_SERVICE"
-        android:protectionLevel="system|signature" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by a {@link android.telecom.ConnectionService},
          to ensure that only the system can bind to it.
@@ -1303,24 +1303,24 @@
          @SystemApi
          @hide -->
     <permission android:name="android.permission.BIND_CONNECTION_SERVICE"
-        android:protectionLevel="system|signature" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by a {@link android.telecom.ConnectionService},
          to ensure that only the system can bind to it.
-         <p>Protection level: system|signature
+         <p>Protection level: signature|privileged
     -->
     <permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
-        android:protectionLevel="system|signature" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to control the in-call experience.
          @hide -->
     <permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE"
-        android:protectionLevel="system|signature" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to receive STK related commands.
          @hide -->
     <permission android:name="android.permission.RECEIVE_STK_COMMANDS"
-        android:protectionLevel="system|signature" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- ================================== -->
     <!-- Permissions for sdcard interaction -->
@@ -1669,12 +1669,12 @@
     <!-- @SystemApi Allows mounting and unmounting file systems for removable storage.
     <p>Not for use by third-party applications.-->
     <permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
-        android:protectionLevel="system|signature" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows formatting file systems for removable storage.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS"
-        android:protectionLevel="system|signature" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows access to ASEC non-destructive API calls
          @hide  -->
@@ -2322,7 +2322,7 @@
          access the network and acquire wakelocks.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST"
-        android:protectionLevel="system|signature" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Permission an application must hold in order to use
          {@link android.provider.Settings#ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS}.
@@ -2530,7 +2530,7 @@
 
     <!-- Allows managing (adding, removing) fingerprint templates. Reserved for the system. @hide -->
     <permission android:name="android.permission.MANAGE_FINGERPRINT"
-        android:protectionLevel="system|signature" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an app to reset fingerprint attempt counter. Reserved for the system. @hide -->
     <permission android:name="android.permission.RESET_FINGERPRINT_LOCKOUT"
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index c1a2038..7aeba81 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1002,6 +1002,10 @@
     <!-- Light sensor event rate in milliseconds for automatic brightness control. -->
     <integer name="config_autoBrightnessLightSensorRate">250</integer>
 
+    <!-- The maximum range of gamma adjustment possible using the screen
+         auto-brightness adjustment setting. -->
+    <fraction name="config_autoBrightnessAdjustmentMaxGamma">300%</fraction>
+
     <!-- If we allow automatic adjustment of screen brightness while dozing, how many times we want
          to reduce it to preserve the battery. Value of 100% means no scaling. -->
     <fraction name="config_screenAutoBrightnessDozeScaleFactor">100%</fraction>
@@ -1019,6 +1023,9 @@
          adapt to the environment.  This mode may be better suited for watches. -->
     <bool name="config_autoBrightnessResetAmbientLuxAfterWarmUp">true</bool>
 
+    <!-- Period of time in which to consider light samples in milliseconds. -->
+    <integer name="config_autoBrightnessAmbientLightHorizon">10000</integer>
+
     <!-- Screen brightness used to dim the screen when the user activity
          timeout expires.  May be less than the minimum allowed brightness setting
          that can be set by the user. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3c9327d..dffaa77 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1689,6 +1689,8 @@
   <java-symbol type="id" name="replace_message" />
   <java-symbol type="fraction" name="config_dimBehindFadeDuration" />
   <java-symbol type="fraction" name="config_screenAutoBrightnessDozeScaleFactor" />
+  <java-symbol type="fraction" name="config_autoBrightnessAdjustmentMaxGamma" />
+  <java-symbol type="integer" name="config_autoBrightnessAmbientLightHorizon"/>
   <java-symbol type="integer" name="config_autoBrightnessBrighteningLightDebounce"/>
   <java-symbol type="integer" name="config_autoBrightnessDarkeningLightDebounce"/>
   <java-symbol type="integer" name="config_autoBrightnessLightSensorRate"/>
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index aa73d44..2763e89 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -117,7 +117,7 @@
 
 void Caches::terminate() {
     if (!mInitialized) return;
-    mRegionMesh.release();
+    mRegionMesh.reset(nullptr);
 
     fboCache.clear();
 
diff --git a/libs/hwui/GammaFontRenderer.cpp b/libs/hwui/GammaFontRenderer.cpp
index 0bcd83a..070c3d7 100644
--- a/libs/hwui/GammaFontRenderer.cpp
+++ b/libs/hwui/GammaFontRenderer.cpp
@@ -194,7 +194,7 @@
 
 void Lookup3GammaFontRenderer::clear() {
     for (int i = 0; i < kGammaCount; i++) {
-        mRenderers[i].release();
+        mRenderers[i].reset(nullptr);
     }
 }
 
@@ -215,7 +215,7 @@
 
     if (count <= 1 || min < 0) return;
 
-    mRenderers[min].release();
+    mRenderers[min].reset(nullptr);
 
     // Also eliminate the caches for large glyphs, as they consume significant memory
     for (int i = 0; i < kGammaCount; ++i) {
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index e16865e..62eeb43 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -251,7 +251,7 @@
 void Layer::cancelDefer() {
     renderNode = nullptr;
     deferredUpdateScheduled = false;
-    deferredList.release();
+    deferredList.reset(nullptr);
 }
 
 void Layer::flush() {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
index 57969ba..6f74203 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -129,7 +129,7 @@
 
             int res = mUtils.getCameraService().supportsCameraApi(cameraId, API_VERSION_2);
 
-            if (res != CameraBinderTestUtils.NO_ERROR && res != CameraBinderTestUtils.EOPNOTSUPP) {
+            if (res != CameraBinderTestUtils.NO_ERROR && res != -android.system.OsConstants.EOPNOTSUPP) {
                 fail("Camera service returned bad value when queried if it supports camera2 api: "
                         + res + " for camera ID " + cameraId);
             }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java
index 6be538a..5c4b23b 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java
@@ -2,6 +2,7 @@
 package com.android.mediaframeworktest.integration;
 
 import static org.junit.Assert.assertNotNull;
+import static android.system.OsConstants.*;
 
 import android.content.Context;
 import android.content.pm.FeatureInfo;
@@ -18,11 +19,10 @@
     static final String CAMERA_SERVICE_BINDER_NAME = "media.camera";
 
     protected static final int USE_CALLING_UID = -1;
-    protected static final int BAD_VALUE = -22;
-    protected static final int INVALID_OPERATION = -38;
-    protected static final int ALREADY_EXISTS = -17;
+    protected static final int BAD_VALUE = -EINVAL;
+    protected static final int INVALID_OPERATION = -ENOSYS;
+    protected static final int ALREADY_EXISTS = -EEXIST;
     public static final int NO_ERROR = 0;
-    public static final int EOPNOTSUPP = -95;
     private final Context mContext;
 
     public CameraBinderTestUtils(Context context) {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsBinderDecoratorTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsBinderDecoratorTest.java
index 727af78..33c6388 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsBinderDecoratorTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsBinderDecoratorTest.java
@@ -27,6 +27,7 @@
 import static org.mockito.Mockito.*;
 import static android.hardware.camera2.utils.CameraBinderDecorator.*;
 import static android.hardware.camera2.CameraAccessException.*;
+import static android.system.OsConstants.*;
 
 import junit.framework.Assert;
 
@@ -78,9 +79,9 @@
             when(mock.doSomethingAlreadyExists()).thenReturn(ALREADY_EXISTS);
             when(mock.doSomethingBadValue()).thenReturn(BAD_VALUE);
             when(mock.doSomethingDeadObject()).thenReturn(DEAD_OBJECT);
-            when(mock.doSomethingBadPolicy()).thenReturn(EACCES);
-            when(mock.doSomethingDeviceBusy()).thenReturn(EBUSY);
-            when(mock.doSomethingNoSuchDevice()).thenReturn(ENODEV);
+            when(mock.doSomethingBadPolicy()).thenReturn(-EACCES);
+            when(mock.doSomethingDeviceBusy()).thenReturn(-EBUSY);
+            when(mock.doSomethingNoSuchDevice()).thenReturn(-ENODEV);
             when(mock.doSomethingUnknownErrorCode()).thenReturn(SOME_ARBITRARY_NEGATIVE_INT);
             when(mock.doSomethingThrowDeadObjectException()).thenThrow(new DeadObjectException());
             when(mock.doSomethingThrowTransactionTooLargeException()).thenThrow(
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index e9f1095..16ea0e4 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -128,6 +128,7 @@
     private boolean mPendingStateChanged;
     private boolean mPendingRecheckAll;
     private long mCollapseTime;
+    private int mLastActiveStream;
 
     public VolumeDialog(Context context, int windowType, VolumeDialogController controller,
             ZenModeController zenModeController, Callback callback) {
@@ -273,10 +274,14 @@
             @Override
             public void onLayoutChange(View v, int left, int top, int right, int bottom,
                     int oldLeft, int oldTop, int oldRight, int oldBottom) {
-                final boolean moved = oldLeft != left || oldTop != top;
+                final boolean moved = mLastActiveStream != mActiveStream ||
+                        oldLeft != left || oldTop != top;
                 if (D.BUG) Log.d(TAG, "onLayoutChange moved=" + moved
                         + " old=" + new Rect(oldLeft, oldTop, oldRight, oldBottom).toShortString()
-                        + " new=" + new Rect(left,top,right,bottom).toShortString());
+                        + "," + mLastActiveStream
+                        + " new=" + new Rect(left,top,right,bottom).toShortString()
+                        + "," + mActiveStream);
+                mLastActiveStream = mActiveStream;
                 if (moved) {
                     for (int i = 0; i < mDialogContentView.getChildCount(); i++) {
                         final View c = mDialogContentView.getChildAt(i);
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index b61f90e..85d0821 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -316,25 +316,9 @@
     }
 
     public void updateRunningAccounts() {
-        mRunningAccounts = AccountManagerService.getSingleton().getRunningAccounts();
-
-        if (mBootCompleted) {
-            doDatabaseCleanup();
-        }
-
-        AccountAndUser[] accounts = mRunningAccounts;
-        for (ActiveSyncContext currentSyncContext : mActiveSyncContexts) {
-            if (!containsAccountAndUser(accounts,
-                    currentSyncContext.mSyncOperation.target.account,
-                    currentSyncContext.mSyncOperation.target.userId)) {
-                Log.d(TAG, "canceling sync since the account is no longer running");
-                sendSyncFinishedOrCanceledMessage(currentSyncContext,
-                        null /* no result since this is a cancel */);
-            }
-        }
-        // we must do this since we don't bother scheduling alarms when
-        // the accounts are not set yet
-        sendCheckAlarmsMessage();
+        if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "sending MESSAGE_ACCOUNTS_UPDATED");
+        // Update accounts in handler thread.
+        mSyncHandler.sendEmptyMessage(SyncHandler.MESSAGE_ACCOUNTS_UPDATED);
     }
 
     private void doDatabaseCleanup() {
@@ -2099,6 +2083,7 @@
          * obj: {@link com.android.server.content.SyncManager.ActiveSyncContext}
          */
         private static final int MESSAGE_MONITOR_SYNC = 8;
+        private static final int MESSAGE_ACCOUNTS_UPDATED = 9;
 
         public final SyncNotificationInfo mSyncNotificationInfo = new SyncNotificationInfo();
         private Long mAlarmScheduleTime = null;
@@ -2216,6 +2201,13 @@
                 // to also take into account the periodic syncs.
                 earliestFuturePollTime = scheduleReadyPeriodicSyncs();
                 switch (msg.what) {
+                    case SyncHandler.MESSAGE_ACCOUNTS_UPDATED:
+                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                            Log.v(TAG, "handleSyncHandlerMessage: MESSAGE_ACCOUNTS_UPDATED");
+                        }
+                        updateRunningAccountsH();
+                        break;
+
                     case SyncHandler.MESSAGE_CANCEL:
                         SyncStorageEngine.EndPoint endpoint = (SyncStorageEngine.EndPoint) msg.obj;
                         Bundle extras = msg.peekData();
@@ -2764,6 +2756,28 @@
             return nextReadyToRunTime;
         }
 
+        private void updateRunningAccountsH() {
+            mRunningAccounts = AccountManagerService.getSingleton().getRunningAccounts();
+
+            if (mBootCompleted) {
+                doDatabaseCleanup();
+            }
+
+            AccountAndUser[] accounts = mRunningAccounts;
+            for (ActiveSyncContext currentSyncContext : mActiveSyncContexts) {
+                if (!containsAccountAndUser(accounts,
+                        currentSyncContext.mSyncOperation.target.account,
+                        currentSyncContext.mSyncOperation.target.userId)) {
+                    Log.d(TAG, "canceling sync since the account is no longer running");
+                    sendSyncFinishedOrCanceledMessage(currentSyncContext,
+                            null /* no result since this is a cancel */);
+                }
+            }
+            // we must do this since we don't bother scheduling alarms when
+            // the accounts are not set yet
+            sendCheckAlarmsMessage();
+        }
+
         private boolean isSyncNotUsingNetworkH(ActiveSyncContext activeSyncContext) {
             final long bytesTransferredCurrent =
                     getTotalBytesTransferredByUid(activeSyncContext.mSyncAdapterUid);
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index e15bca6..1908f72 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -49,23 +49,12 @@
     // If true, enables the use of the screen auto-brightness adjustment setting.
     private static final boolean USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT = true;
 
-    // The maximum range of gamma adjustment possible using the screen
-    // auto-brightness adjustment setting.
-    private static final float SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA = 3.0f;
-
-    // Period of time in which to consider light samples in milliseconds.
-    private static final int AMBIENT_LIGHT_HORIZON = 10000;
-
     // Hysteresis constraints for brightening or darkening.
     // The recent lux must have changed by at least this fraction relative to the
     // current ambient lux before a change will be considered.
     private static final float BRIGHTENING_LIGHT_HYSTERESIS = 0.10f;
     private static final float DARKENING_LIGHT_HYSTERESIS = 0.20f;
 
-    // The intercept used for the weighting calculation. This is used in order to keep all possible
-    // weighting values positive.
-    private static final int WEIGHTING_INTERCEPT = AMBIENT_LIGHT_HORIZON;
-
     // How long the current sensor reading is assumed to be valid beyond the current time.
     // This provides a bit of prediction, as well as ensures that the weight for the last sample is
     // non-zero, which in turn ensures that the total weight is non-zero.
@@ -132,6 +121,13 @@
     // and only then decide whether to change brightness.
     private final boolean mResetAmbientLuxAfterWarmUpConfig;
 
+    // Period of time in which to consider light samples in milliseconds.
+    private final int mAmbientLightHorizon;
+
+    // The intercept used for the weighting calculation. This is used in order to keep all possible
+    // weighting values positive.
+    private final int mWeightingIntercept;
+
     // Amount of time to delay auto-brightness after screen on while waiting for
     // the light sensor to warm-up in milliseconds.
     // May be 0 if no warm-up is required.
@@ -179,6 +175,10 @@
     // The screen auto-brightness adjustment factor in the range -1 (dimmer) to 1 (brighter)
     private float mScreenAutoBrightnessAdjustment = 0.0f;
 
+    // The maximum range of gamma adjustment possible using the screen
+    // auto-brightness adjustment setting.
+    private float mScreenAutoBrightnessAdjustmentMaxGamma;
+
     // The last screen auto-brightness gamma.  (For printing in dump() only.)
     private float mLastScreenAutoBrightnessGamma = 1.0f;
 
@@ -197,7 +197,8 @@
             SensorManager sensorManager, Spline autoBrightnessSpline, int lightSensorWarmUpTime,
             int brightnessMin, int brightnessMax, float dozeScaleFactor,
             int lightSensorRate, long brighteningLightDebounceConfig,
-            long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig) {
+            long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig,
+            int ambientLightHorizon, float autoBrightnessAdjustmentMaxGamma ) {
         mCallbacks = callbacks;
         mTwilight = LocalServices.getService(TwilightManager.class);
         mSensorManager = sensorManager;
@@ -210,9 +211,12 @@
         mBrighteningLightDebounceConfig = brighteningLightDebounceConfig;
         mDarkeningLightDebounceConfig = darkeningLightDebounceConfig;
         mResetAmbientLuxAfterWarmUpConfig = resetAmbientLuxAfterWarmUpConfig;
+        mAmbientLightHorizon = ambientLightHorizon;
+        mWeightingIntercept = ambientLightHorizon;
+        mScreenAutoBrightnessAdjustmentMaxGamma = autoBrightnessAdjustmentMaxGamma;
 
         mHandler = new AutomaticBrightnessHandler(looper);
-        mAmbientLightRingBuffer = new AmbientLightRingBuffer(mLightSensorRate);
+        mAmbientLightRingBuffer = new AmbientLightRingBuffer(mLightSensorRate, mAmbientLightHorizon);
 
         if (!DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
             mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
@@ -266,6 +270,7 @@
         pw.println("  mLightSensorEnabled=" + mLightSensorEnabled);
         pw.println("  mLightSensorEnableTime=" + TimeUtils.formatUptime(mLightSensorEnableTime));
         pw.println("  mAmbientLux=" + mAmbientLux);
+        pw.println("  mAmbientLightHorizon=" + mAmbientLightHorizon);
         pw.println("  mBrighteningLuxThreshold=" + mBrighteningLuxThreshold);
         pw.println("  mDarkeningLuxThreshold=" + mDarkeningLuxThreshold);
         pw.println("  mLastObservedLux=" + mLastObservedLux);
@@ -274,6 +279,7 @@
         pw.println("  mAmbientLightRingBuffer=" + mAmbientLightRingBuffer);
         pw.println("  mScreenAutoBrightness=" + mScreenAutoBrightness);
         pw.println("  mScreenAutoBrightnessAdjustment=" + mScreenAutoBrightnessAdjustment);
+        pw.println("  mScreenAutoBrightnessAdjustmentMaxGamma=" + mScreenAutoBrightnessAdjustmentMaxGamma);
         pw.println("  mLastScreenAutoBrightnessGamma=" + mLastScreenAutoBrightnessGamma);
         pw.println("  mDozing=" + mDozing);
     }
@@ -309,7 +315,7 @@
 
     private void applyLightSensorMeasurement(long time, float lux) {
         mRecentLightSamples++;
-        mAmbientLightRingBuffer.prune(time - AMBIENT_LIGHT_HORIZON);
+        mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon);
         mAmbientLightRingBuffer.push(time, lux);
 
         // Remember this sample value.
@@ -360,14 +366,14 @@
         return sum / totalWeight;
     }
 
-    private static float calculateWeight(long startDelta, long endDelta) {
+    private float calculateWeight(long startDelta, long endDelta) {
         return weightIntegral(endDelta) - weightIntegral(startDelta);
     }
 
-    // Evaluates the integral of y = x + WEIGHTING_INTERCEPT. This is always positive for the
+    // Evaluates the integral of y = x + mWeightingIntercept. This is always positive for the
     // horizon we're looking at and provides a non-linear weighting for light samples.
-    private static float weightIntegral(long x) {
-        return x * (x * 0.5f + WEIGHTING_INTERCEPT);
+    private float weightIntegral(long x) {
+        return x * (x * 0.5f + mWeightingIntercept);
     }
 
     private long nextAmbientLightBrighteningTransition(long time) {
@@ -396,7 +402,7 @@
 
     private void updateAmbientLux() {
         long time = SystemClock.uptimeMillis();
-        mAmbientLightRingBuffer.prune(time - AMBIENT_LIGHT_HORIZON);
+        mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon);
         updateAmbientLux(time);
     }
 
@@ -470,7 +476,7 @@
 
         if (USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT
                 && mScreenAutoBrightnessAdjustment != 0.0f) {
-            final float adjGamma = MathUtils.pow(SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA,
+            final float adjGamma = MathUtils.pow(mScreenAutoBrightnessAdjustmentMaxGamma,
                     Math.min(1.0f, Math.max(-1.0f, -mScreenAutoBrightnessAdjustment)));
             gamma *= adjGamma;
             if (DEBUG) {
@@ -653,8 +659,8 @@
         private int mEnd;
         private int mCount;
 
-        public AmbientLightRingBuffer(long lightSensorRate) {
-            mCapacity = (int) Math.ceil(AMBIENT_LIGHT_HORIZON * BUFFER_SLACK / lightSensorRate);
+        public AmbientLightRingBuffer(long lightSensorRate, int ambientLightHorizon) {
+            mCapacity = (int) Math.ceil(ambientLightHorizon * BUFFER_SLACK / lightSensorRate);
             mRingLux = new float[mCapacity];
             mRingTime = new long[mCapacity];
         }
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 7b49530..433d887 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -311,6 +311,11 @@
                 com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce);
         boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean(
                 com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);
+        int ambientLightHorizon = resources.getInteger(
+                com.android.internal.R.integer.config_autoBrightnessAmbientLightHorizon);
+        float autoBrightnessAdjustmentMaxGamma = resources.getFraction(
+                com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma,
+                1, 1);
 
         if (mUseSoftwareAutoBrightnessConfig) {
             int[] lux = resources.getIntArray(
@@ -348,7 +353,8 @@
                         lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum,
                         mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
                         brighteningLightDebounce, darkeningLightDebounce,
-                        autoBrightnessResetAmbientLuxAfterWarmUp);
+                        autoBrightnessResetAmbientLuxAfterWarmUp,
+                        ambientLightHorizon, autoBrightnessAdjustmentMaxGamma);
             }
         }
 
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
index 69b2a9d..0c36063 100644
--- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
@@ -44,4 +44,12 @@
         }
         return anchor.getTrustedCert();
     }
+
+    public X509Certificate findByIssuerAndSignature(X509Certificate cert) {
+        java.security.cert.TrustAnchor anchor = mIndex.findByIssuerAndSignature(cert);
+        if (anchor == null) {
+            return null;
+        }
+        return anchor.getTrustedCert();
+    }
 }
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java
index 998bb68..35e3ef4 100644
--- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java
@@ -22,6 +22,7 @@
 import android.util.ArraySet;
 import android.util.Pair;
 import java.io.IOException;
+import java.net.InetAddress;
 import java.net.Socket;
 import java.net.URL;
 import java.security.KeyStore;
@@ -34,6 +35,7 @@
 import javax.net.ssl.HttpsURLConnection;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLSocket;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.TrustManagerFactory;
 
@@ -103,6 +105,15 @@
         TestUtils.assertConnectionFails(context, "developer.android.com", 443);
         TestUtils.assertUrlConnectionFails(context, "google.com", 443);
         TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
+        // Check that sockets created without the hostname fail with per-domain configs
+        SSLSocket socket = (SSLSocket) context.getSocketFactory()
+                .createSocket(InetAddress.getByName("android.com"), 443);
+        try {
+        socket.startHandshake();
+        socket.getInputStream();
+        fail();
+        } catch (IOException expected) {
+        }
     }
 
     public void testBasicPinning() throws Exception {