Merge "Add logging constants for SUW A11y (Vision Settings) screens. Bug: 27777706" into nyc-dev
diff --git a/api/current.txt b/api/current.txt
index c81284b..298f6c4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5893,7 +5893,7 @@
     method public boolean hasGrantedPolicy(android.content.ComponentName, int);
     method public boolean installCaCert(android.content.ComponentName, byte[]);
     method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String);
-    method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String, boolean);
+    method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, boolean);
     method public boolean isActivePasswordSufficient();
     method public boolean isAdminActive(android.content.ComponentName);
     method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String);
diff --git a/api/system-current.txt b/api/system-current.txt
index 071d1f1..0651c61 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6039,7 +6039,7 @@
     method public boolean hasGrantedPolicy(android.content.ComponentName, int);
     method public boolean installCaCert(android.content.ComponentName, byte[]);
     method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String);
-    method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String, boolean);
+    method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, boolean);
     method public boolean isActivePasswordSufficient();
     method public boolean isAdminActive(android.content.ComponentName);
     method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String);
@@ -26819,7 +26819,9 @@
     method public void configureWifiChange(android.net.wifi.WifiScanner.WifiChangeSettings);
     method public boolean getScanResults();
     method public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener);
+    method public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener, android.os.WorkSource);
     method public void startScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener);
+    method public void startScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener, android.os.WorkSource);
     method public void startTrackingBssids(android.net.wifi.WifiScanner.BssidInfo[], int, android.net.wifi.WifiScanner.BssidListener);
     method public void startTrackingWifiChange(android.net.wifi.WifiScanner.WifiChangeListener);
     method public void stopBackgroundScan(android.net.wifi.WifiScanner.ScanListener);
diff --git a/api/test-current.txt b/api/test-current.txt
index 8216146..2a9f452 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5897,7 +5897,7 @@
     method public boolean hasGrantedPolicy(android.content.ComponentName, int);
     method public boolean installCaCert(android.content.ComponentName, byte[]);
     method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String);
-    method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String, boolean);
+    method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, boolean);
     method public boolean isActivePasswordSufficient();
     method public boolean isAdminActive(android.content.ComponentName);
     method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index e1afb17..36c82e5 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -71,6 +71,7 @@
 import java.security.spec.InvalidKeySpecException;
 import java.security.spec.PKCS8EncodedKeySpec;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
@@ -2782,7 +2783,7 @@
      * compromised, certificates it had already installed will be protected.
      *
      * <p>If the installer must have access to the credentials, call
-     * {@link #installKeyPair(ComponentName, PrivateKey, Certificate, String, boolean)} instead.
+     * {@link #installKeyPair(ComponentName, PrivateKey, Certificate[], String, boolean)} instead.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
      *            {@code null} if calling from a delegated certificate installer.
@@ -2796,13 +2797,14 @@
      */
     public boolean installKeyPair(@Nullable ComponentName admin, @NonNull PrivateKey privKey,
             @NonNull Certificate cert, @NonNull String alias) {
-        return installKeyPair(admin, privKey, cert, alias, false);
+        return installKeyPair(admin, privKey, new Certificate[] {cert}, alias, false);
     }
 
     /**
      * Called by a device or profile owner, or delegated certificate installer, to install a
-     * certificate and corresponding private key. All apps within the profile will be able to access
-     * the certificate and use the private key, given direct user approval.
+     * certificate chain and corresponding private key for the leaf certificate. All apps within the
+     * profile will be able to access the certificate chain and use the private key, given direct
+     * user approval.
      *
      * <p>The caller of this API may grant itself access to the certificate and private key
      * immediately, without user approval. It is a best practice not to request this unless strictly
@@ -2811,7 +2813,9 @@
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
      *        {@code null} if calling from a delegated certificate installer.
      * @param privKey The private key to install.
-     * @param cert The certificate to install.
+     * @param certs The certificate chain to install. The chain should start with the leaf
+     *        certificate and include the chain of trust in order. This will be returned by
+     *        {@link android.security.KeyChain#getCertificateChain}.
      * @param alias The private key alias under which to install the certificate. If a certificate
      *        with that alias already exists, it will be overwritten.
      * @param requestAccess {@code true} to request that the calling app be granted access to the
@@ -2820,14 +2824,20 @@
      * @return {@code true} if the keys were installed, {@code false} otherwise.
      * @throws SecurityException if {@code admin} is not {@code null} and not a device or profile
      *         owner.
+     * @see android.security.KeyChain#getCertificateChain
      */
     public boolean installKeyPair(@Nullable ComponentName admin, @NonNull PrivateKey privKey,
-            @NonNull Certificate cert, @NonNull String alias, boolean requestAccess) {
+            @NonNull Certificate[] certs, @NonNull String alias, boolean requestAccess) {
         try {
-            final byte[] pemCert = Credentials.convertToPem(cert);
+            final byte[] pemCert = Credentials.convertToPem(certs[0]);
+            byte[] pemChain = null;
+            if (certs.length > 1) {
+                pemChain = Credentials.convertToPem(Arrays.copyOfRange(certs, 1, certs.length));
+            }
             final byte[] pkcs8Key = KeyFactory.getInstance(privKey.getAlgorithm())
                     .getKeySpec(privKey, PKCS8EncodedKeySpec.class).getEncoded();
-            return mService.installKeyPair(admin, pkcs8Key, pemCert, alias, requestAccess);
+            return mService.installKeyPair(admin, pkcs8Key, pemCert, pemChain, alias,
+                    requestAccess);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 97383a3..8be52d8 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -146,7 +146,7 @@
     void enforceCanManageCaCerts(in ComponentName admin);
 
     boolean installKeyPair(in ComponentName who, in byte[] privKeyBuffer, in byte[] certBuffer,
-            String alias, boolean requestAccess);
+            in byte[] certChainBuffer, String alias, boolean requestAccess);
     boolean removeKeyPair(in ComponentName who, String alias);
     void choosePrivateKeyAlias(int uid, in Uri uri, in String alias, IBinder aliasCallback);
 
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index b75e653..7d903bd 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -31,12 +31,15 @@
 import android.util.SparseIntArray;
 import dalvik.system.CloseGuard;
 
+import com.android.internal.annotations.GuardedBy;
+
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+
 /**
  * Sensor manager implementation that communicates with the built-in
  * system sensors.
@@ -55,7 +58,9 @@
     private static native boolean nativeIsDataInjectionEnabled(long nativeInstance);
 
     private static final Object sLock = new Object();
-    private static boolean sSensorModuleInitialized = false;
+    @GuardedBy("sLock")
+    private static boolean sNativeClassInited = false;
+    @GuardedBy("sLock")
     private static InjectEventQueue sInjectEventQueue = null;
 
     private final ArrayList<Sensor> mFullSensorsList = new ArrayList<>();
@@ -84,8 +89,8 @@
     /** {@hide} */
     public SystemSensorManager(Context context, Looper mainLooper) {
         synchronized(sLock) {
-            if (!sSensorModuleInitialized) {
-                sSensorModuleInitialized = true;
+            if (!sNativeClassInited) {
+                sNativeClassInited = true;
                 nativeClassInit();
             }
         }
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index f16fdd6..00f368e 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -325,16 +325,24 @@
 
         if (getChildCount() > 0) {
             final View child = getChildAt(0);
-            int width = getMeasuredWidth();
-            if (child.getMeasuredWidth() < width) {
-                final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            final int widthPadding;
+            final int heightPadding;
+            final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
+            if (targetSdkVersion >= Build.VERSION_CODES.M) {
+                widthPadding = mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin;
+                heightPadding = mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin;
+            } else {
+                widthPadding = mPaddingLeft + mPaddingRight;
+                heightPadding = mPaddingTop + mPaddingBottom;
+            }
 
-                int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, mPaddingTop
-                        + mPaddingBottom, lp.height);
-                width -= mPaddingLeft;
-                width -= mPaddingRight;
-                int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
-
+            int desiredWidth = getMeasuredWidth() - widthPadding;
+            if (child.getMeasuredWidth() < desiredWidth) {
+                final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+                        desiredWidth, MeasureSpec.EXACTLY);
+                final int childHeightMeasureSpec = getChildMeasureSpec(
+                        heightMeasureSpec, heightPadding, lp.height);
                 child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
             }
         }
@@ -1235,17 +1243,17 @@
     }
 
     @Override
-    protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) {
+    protected void measureChild(View child, int parentWidthMeasureSpec,
+            int parentHeightMeasureSpec) {
         ViewGroup.LayoutParams lp = child.getLayoutParams();
 
-        int childWidthMeasureSpec;
-        int childHeightMeasureSpec;
+        final int horizontalPadding = mPaddingLeft + mPaddingRight;
+        final int childWidthMeasureSpec = MeasureSpec.makeSafeMeasureSpec(
+                Math.max(0, MeasureSpec.getSize(parentWidthMeasureSpec) - horizontalPadding),
+                MeasureSpec.UNSPECIFIED);
 
-        childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec, mPaddingTop
-                + mPaddingBottom, lp.height);
-
-        childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-
+        final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
+                mPaddingTop + mPaddingBottom, lp.height);
         child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
     }
 
@@ -1257,8 +1265,11 @@
         final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
                 mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin
                         + heightUsed, lp.height);
-        final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
-                lp.leftMargin + lp.rightMargin, MeasureSpec.UNSPECIFIED);
+        final int usedTotal = mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin +
+                widthUsed;
+        final int childWidthMeasureSpec = MeasureSpec.makeSafeMeasureSpec(
+                Math.max(0, MeasureSpec.getSize(parentWidthMeasureSpec) - usedTotal),
+                MeasureSpec.UNSPECIFIED);
 
         child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
     }
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 3f7a07b..0555cd4 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -350,24 +350,24 @@
 
         if (getChildCount() > 0) {
             final View child = getChildAt(0);
-            final int height = getMeasuredHeight();
-            if (child.getMeasuredHeight() < height) {
-                final int widthPadding;
-                final int heightPadding;
-                final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
-                final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
-                if (targetSdkVersion >= VERSION_CODES.M) {
-                    widthPadding = mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin;
-                    heightPadding = mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin;
-                } else {
-                    widthPadding = mPaddingLeft + mPaddingRight;
-                    heightPadding = mPaddingTop + mPaddingBottom;
-                }
+            final int widthPadding;
+            final int heightPadding;
+            final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
+            final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            if (targetSdkVersion >= VERSION_CODES.M) {
+                widthPadding = mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin;
+                heightPadding = mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin;
+            } else {
+                widthPadding = mPaddingLeft + mPaddingRight;
+                heightPadding = mPaddingTop + mPaddingBottom;
+            }
 
+            final int desiredHeight = getMeasuredHeight() - heightPadding;
+            if (child.getMeasuredHeight() < desiredHeight) {
                 final int childWidthMeasureSpec = getChildMeasureSpec(
                         widthMeasureSpec, widthPadding, lp.width);
                 final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
-                        height - heightPadding, MeasureSpec.EXACTLY);
+                        desiredHeight, MeasureSpec.EXACTLY);
                 child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
             }
         }
@@ -1268,9 +1268,10 @@
 
         childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec, mPaddingLeft
                 + mPaddingRight, lp.width);
-
+        final int verticalPadding = mPaddingTop + mPaddingBottom;
         childHeightMeasureSpec = MeasureSpec.makeSafeMeasureSpec(
-                MeasureSpec.getSize(parentHeightMeasureSpec), MeasureSpec.UNSPECIFIED);
+                Math.max(0, MeasureSpec.getSize(parentHeightMeasureSpec) - verticalPadding),
+                MeasureSpec.UNSPECIFIED);
 
         child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
     }
@@ -1283,8 +1284,11 @@
         final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
                 mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
                         + widthUsed, lp.width);
+        final int usedTotal = mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin +
+                heightUsed;
         final int childHeightMeasureSpec = MeasureSpec.makeSafeMeasureSpec(
-                MeasureSpec.getSize(parentHeightMeasureSpec), MeasureSpec.UNSPECIFIED);
+                Math.max(0, MeasureSpec.getSize(parentHeightMeasureSpec) - usedTotal),
+                MeasureSpec.UNSPECIFIED);
 
         child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
     }
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index e39bb1c..90f407f 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -36,15 +36,17 @@
 
 #include "core_jni_helpers.h"
 
-static struct {
+namespace {
+
+using namespace android;
+
+struct {
     jclass clazz;
     jmethodID dispatchSensorEvent;
     jmethodID dispatchFlushCompleteEvent;
     jmethodID dispatchAdditionalInfoEvent;
 } gBaseEventQueueClassInfo;
 
-namespace android {
-
 struct SensorOffsets
 {
     jclass      clazz;
@@ -72,9 +74,9 @@
 } gListOffsets;
 
 /*
- * The method below are not thread-safe and not intended to be
+ * nativeClassInit is not inteneded to be thread-safe. It should be called before other native...
+ * functions (except nativeCreate).
  */
-
 static void
 nativeClassInit (JNIEnv *_env, jclass _this)
 {
@@ -494,9 +496,7 @@
             (void*)nativeInjectSensorData },
 };
 
-}; // namespace android
-
-using namespace android;
+} //unnamed namespace
 
 int register_android_hardware_SensorManager(JNIEnv *env)
 {
diff --git a/keystore/java/android/security/IKeyChainService.aidl b/keystore/java/android/security/IKeyChainService.aidl
index cfcb4e0..deea972 100644
--- a/keystore/java/android/security/IKeyChainService.aidl
+++ b/keystore/java/android/security/IKeyChainService.aidl
@@ -27,12 +27,13 @@
     // APIs used by KeyChain
     String requestPrivateKey(String alias);
     byte[] getCertificate(String alias);
+    byte[] getCaCertificates(String alias);
 
     // APIs used by CertInstaller
     void installCaCertificate(in byte[] caCertificate);
 
     // APIs used by DevicePolicyManager
-    boolean installKeyPair(in byte[] privateKey, in byte[] userCert, String alias);
+    boolean installKeyPair(in byte[] privateKey, in byte[] userCert, in byte[] certChain, String alias);
     boolean removeKeyPair(String alias);
 
     // APIs used by Settings
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 0886487..cce58c2 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -42,6 +42,8 @@
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.BlockingQueue;
@@ -389,7 +391,12 @@
 
     /**
      * Returns the {@code X509Certificate} chain for the requested
-     * alias, or null if no there is no result.
+     * alias, or null if there is no result.
+     * <p>
+     * <strong>Note:</strong> If a certificate chain was explicitly specified when the alias was
+     * installed, this method will return that chain. If only the client certificate was specified
+     * at the installation time, this method will try to build a certificate chain using all
+     * available trust anchors (preinstalled and user-added).
      *
      * <p> This method may block while waiting for a connection to another process, and must never
      * be called from the main thread.
@@ -413,11 +420,31 @@
             if (certificateBytes == null) {
                 return null;
             }
-
-            TrustedCertificateStore store = new TrustedCertificateStore();
-            List<X509Certificate> chain = store
-                    .getCertificateChain(toCertificate(certificateBytes));
-            return chain.toArray(new X509Certificate[chain.size()]);
+            X509Certificate leafCert = toCertificate(certificateBytes);
+            final byte[] certChainBytes = keyChainService.getCaCertificates(alias);
+            // If the keypair is installed with a certificate chain by either
+            // DevicePolicyManager.installKeyPair or CertInstaller, return that chain.
+            if (certChainBytes != null && certChainBytes.length != 0) {
+                Collection<X509Certificate> chain = toCertificates(certChainBytes);
+                ArrayList<X509Certificate> fullChain = new ArrayList<>(chain.size() + 1);
+                fullChain.add(leafCert);
+                fullChain.addAll(chain);
+                return fullChain.toArray(new X509Certificate[fullChain.size()]);
+            } else {
+                // If there isn't a certificate chain, either due to a pre-existing keypair
+                // installed before N, or no chain is explicitly installed under the new logic,
+                // fall back to old behavior of constructing the chain from trusted credentials.
+                //
+                // This logic exists to maintain old behaviour for already installed keypair, at
+                // the cost of potentially returning extra certificate chain for new clients who
+                // explicitly installed only the client certificate without a chain. The latter
+                // case is actually no different from pre-N behaviour of getCertificateChain(),
+                // in that sense this change introduces no regression. Besides the returned chain
+                // is still valid so the consumer of the chain should have no problem verifying it.
+                TrustedCertificateStore store = new TrustedCertificateStore();
+                List<X509Certificate> chain = store.getCertificateChain(leafCert);
+                return chain.toArray(new X509Certificate[chain.size()]);
+            }
         } catch (CertificateException e) {
             throw new KeyChainException(e);
         } catch (RemoteException e) {
@@ -486,6 +513,21 @@
         }
     }
 
+    /** @hide */
+    @NonNull
+    public static Collection<X509Certificate> toCertificates(@NonNull byte[] bytes) {
+        if (bytes == null) {
+            throw new IllegalArgumentException("bytes == null");
+        }
+        try {
+            CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+            return (Collection<X509Certificate>) certFactory.generateCertificates(
+                    new ByteArrayInputStream(bytes));
+        } catch (CertificateException e) {
+            throw new AssertionError(e);
+        }
+    }
+
     /**
      * @hide for reuse by CertInstaller and Settings.
      * @see KeyChain#bind
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 899b0ef..a05818a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -119,12 +119,18 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         TunerService.get(mContext).addTunable(this, QS_SHOW_BRIGHTNESS);
+        if (mHost != null) {
+            setTiles(mHost.getTiles());
+        }
     }
 
     @Override
     protected void onDetachedFromWindow() {
         TunerService.get(mContext).removeTunable(this);
         mHost.removeCallback(this);
+        for (TileRecord record : mRecords) {
+            record.tile.removeCallbacks();
+        }
         super.onDetachedFromWindow();
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index fdbbd85..926ff37 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -6962,10 +6962,11 @@
                 // If the cache was pruned, any compiled odex files will likely be out of date
                 // and would have to be patched (would be SELF_PATCHOAT, which is deprecated).
                 // Instead, force the extraction in this case.
-                performDexOpt(pkg.packageName, null /* instructionSet */,
-                         false /* checkProfiles */,
-                         causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
-                         causePrunedCache);
+                performDexOpt(pkg.packageName,
+                        null /* instructionSet */,
+                        false /* checkProfiles */,
+                        causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
+                        false /* force */);
             }
         }
     }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 0e80147..3e368f5 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -4138,8 +4138,8 @@
     }
 
     @Override
-    public boolean installKeyPair(ComponentName who, byte[] privKey, byte[] cert, String alias,
-            boolean requestAccess) {
+    public boolean installKeyPair(ComponentName who, byte[] privKey, byte[] cert, byte[] chain,
+            String alias, boolean requestAccess) {
         enforceCanManageInstalledKeys(who);
 
         final int callingUid = mInjector.binderGetCallingUid();
@@ -4149,7 +4149,7 @@
                     KeyChain.bindAsUser(mContext, UserHandle.getUserHandleForUid(callingUid));
             try {
                 IKeyChainService keyChain = keyChainConnection.getService();
-                if (!keyChain.installKeyPair(privKey, cert, alias)) {
+                if (!keyChain.installKeyPair(privKey, cert, chain, alias)) {
                     return false;
                 }
                 if (requestAccess) {
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 508bdff..bd4220f 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -27,6 +27,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
+import android.os.WorkSource;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -661,12 +662,26 @@
      *                 scans should also not share this object.
      */
     public void startBackgroundScan(ScanSettings settings, ScanListener listener) {
+        startBackgroundScan(settings, listener, null);
+    }
+
+    /** start wifi scan in background
+     * @param settings specifies various parameters for the scan; for more information look at
+     * {@link ScanSettings}
+     * @param workSource WorkSource to blame for power usage
+     * @param listener specifies the object to report events to. This object is also treated as a
+     *                 key for this scan, and must also be specified to cancel the scan. Multiple
+     *                 scans should also not share this object.
+     */
+    public void startBackgroundScan(ScanSettings settings, ScanListener listener,
+            WorkSource workSource) {
         Preconditions.checkNotNull(listener, "listener cannot be null");
         int key = addListener(listener);
         if (key == INVALID_KEY) return;
         validateChannel();
         sAsyncChannel.sendMessage(CMD_START_BACKGROUND_SCAN, 0, key, settings);
     }
+
     /**
      * stop an ongoing wifi scan
      * @param listener specifies which scan to cancel; must be same object as passed in {@link
@@ -698,6 +713,19 @@
      *                 scans should also not share this object.
      */
     public void startScan(ScanSettings settings, ScanListener listener) {
+        startScan(settings, listener, null);
+    }
+
+    /**
+     * starts a single scan and reports results asynchronously
+     * @param settings specifies various parameters for the scan; for more information look at
+     * {@link ScanSettings}
+     * @param workSource WorkSource to blame for power usage
+     * @param listener specifies the object to report events to. This object is also treated as a
+     *                 key for this scan, and must also be specified to cancel the scan. Multiple
+     *                 scans should also not share this object.
+     */
+    public void startScan(ScanSettings settings, ScanListener listener, WorkSource workSource) {
         Preconditions.checkNotNull(listener, "listener cannot be null");
         int key = addListener(listener);
         if (key == INVALID_KEY) return;