Merge "Allow notfication vibrations in DND" into rvc-qpr-dev
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index dc16125..13bf197 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -554,6 +554,10 @@
             return NO_ERROR;
         }
         if (!args[0].compare(String8("section"))) {
+            if (argCount == 1) {
+                fprintf(out, "Not enough arguments for section\n");
+                return NO_ERROR;
+            }
             int id = atoi(args[1]);
             int idx = 0;
             while (SECTION_LIST[idx] != NULL) {
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 986e6ea..9d4ab0b 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -72,6 +72,7 @@
 import android.util.Size;
 
 import dalvik.annotation.optimization.FastNative;
+import dalvik.system.VMRuntime;
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
@@ -351,6 +352,7 @@
         if (mMetadataPtr == 0) {
             throw new OutOfMemoryError("Failed to allocate native CameraMetadata");
         }
+        updateNativeAllocation();
     }
 
     /**
@@ -362,6 +364,7 @@
         if (mMetadataPtr == 0) {
             throw new OutOfMemoryError("Failed to allocate native CameraMetadata");
         }
+        updateNativeAllocation();
     }
 
     /**
@@ -443,6 +446,7 @@
 
     public void readFromParcel(Parcel in) {
         nativeReadFromParcel(in, mMetadataPtr);
+        updateNativeAllocation();
     }
 
     /**
@@ -533,6 +537,11 @@
         // Delete native pointer, but does not clear it
         nativeClose(mMetadataPtr);
         mMetadataPtr = 0;
+
+        if (mBufferSize > 0) {
+            VMRuntime.getRuntime().registerNativeFree(mBufferSize);
+        }
+        mBufferSize = 0;
     }
 
     private <T> T getBase(CameraCharacteristics.Key<T> key) {
@@ -1645,9 +1654,26 @@
         return true;
     }
 
+    private void updateNativeAllocation() {
+        long currentBufferSize = nativeGetBufferSize(mMetadataPtr);
+
+        if (currentBufferSize != mBufferSize) {
+            if (mBufferSize > 0) {
+                VMRuntime.getRuntime().registerNativeFree(mBufferSize);
+            }
+
+            mBufferSize = currentBufferSize;
+
+            if (mBufferSize > 0) {
+                VMRuntime.getRuntime().registerNativeAllocation(mBufferSize);
+            }
+        }
+    }
+
     private int mCameraId = -1;
     private boolean mHasMandatoryConcurrentStreams = false;
     private Size mDisplaySize = new Size(0, 0);
+    private long mBufferSize = 0;
 
     /**
      * Set the current camera Id.
@@ -1705,6 +1731,8 @@
     private static synchronized native boolean nativeIsEmpty(long ptr);
     @FastNative
     private static synchronized native int nativeGetEntryCount(long ptr);
+    @FastNative
+    private static synchronized native long nativeGetBufferSize(long ptr);
 
     @UnsupportedAppUsage
     @FastNative
@@ -1744,6 +1772,8 @@
         mCameraId = other.mCameraId;
         mHasMandatoryConcurrentStreams = other.mHasMandatoryConcurrentStreams;
         mDisplaySize = other.mDisplaySize;
+        updateNativeAllocation();
+        other.updateNativeAllocation();
     }
 
     /**
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 76c2f2e..460561b 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -1761,7 +1761,7 @@
                 case ChooserListAdapter.TARGET_CALLER:
                 case ChooserListAdapter.TARGET_STANDARD:
                     cat = MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET;
-                    value -= currentListAdapter.getSelectableServiceTargetCount();
+                    value -= currentListAdapter.getSurfacedTargetInfo().size();
                     numCallerProvided = currentListAdapter.getCallerTargetCount();
                     getChooserActivityLogger().logShareTargetSelected(
                             SELECTION_TYPE_APP,
diff --git a/core/jni/android_hardware_camera2_CameraMetadata.cpp b/core/jni/android_hardware_camera2_CameraMetadata.cpp
index 9ad4cd9..b5955c4 100644
--- a/core/jni/android_hardware_camera2_CameraMetadata.cpp
+++ b/core/jni/android_hardware_camera2_CameraMetadata.cpp
@@ -249,6 +249,16 @@
     return metadata->entryCount();
 }
 
+static jlong CameraMetadata_getBufferSize(JNIEnv *env, jclass thiz, jlong ptr) {
+    ALOGV("%s", __FUNCTION__);
+
+    CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, ptr);
+
+    if (metadata == NULL) return 0;
+
+    return metadata->bufferSize();
+}
+
 // idempotent. calling more than once has no effect.
 static void CameraMetadata_close(JNIEnv *env, jclass thiz, jlong ptr) {
     ALOGV("%s", __FUNCTION__);
@@ -552,6 +562,9 @@
   { "nativeGetEntryCount",
     "(J)I",
     (void*)CameraMetadata_getEntryCount },
+  { "nativeGetBufferSize",
+    "(J)J",
+    (void*)CameraMetadata_getBufferSize },
   { "nativeClose",
     "(J)V",
     (void*)CameraMetadata_close },
diff --git a/drm/jni/Android.bp b/drm/jni/Android.bp
index 1e33f0e..68757d8 100644
--- a/drm/jni/Android.bp
+++ b/drm/jni/Android.bp
@@ -21,6 +21,7 @@
 
     shared_libs: [
         "libdrmframework",
+        "libdrmframeworkcommon",
         "liblog",
         "libutils",
         "libandroid_runtime",
diff --git a/services/core/java/com/android/server/biometrics/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
index edc8f15..8ca37b81 100644
--- a/services/core/java/com/android/server/biometrics/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
@@ -16,16 +16,22 @@
 
 package com.android.server.biometrics;
 
+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.BiometricsProtoEnums;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.security.KeyStore;
+import android.util.EventLog;
 import android.util.Slog;
 
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * A class to keep track of the authentication state for a given client.
@@ -148,7 +154,54 @@
                     + ", requireConfirmation: " + mRequireConfirmation
                     + ", user: " + getTargetUserId());
 
+            // Ensure authentication only succeeds if the client activity is on top or is keyguard.
+            boolean isBackgroundAuth = false;
+            if (authenticated && !Utils.isKeyguard(getContext(), getOwnerString())) {
+                try {
+                    final List<ActivityManager.RunningTaskInfo> tasks =
+                            ActivityTaskManager.getService().getTasks(1);
+                    if (tasks == null || tasks.isEmpty()) {
+                        Slog.e(TAG, "No running tasks reported");
+                        isBackgroundAuth = true;
+                    } else {
+                        final ComponentName topActivity = tasks.get(0).topActivity;
+                        if (topActivity == null) {
+                            Slog.e(TAG, "Unable to get top activity");
+                            isBackgroundAuth = true;
+                        } else {
+                            final String topPackage = topActivity.getPackageName();
+                            if (!topPackage.contentEquals(getOwnerString())) {
+                                Slog.e(TAG, "Background authentication detected, top: " + topPackage
+                                        + ", client: " + this);
+                                isBackgroundAuth = true;
+                            }
+                        }
+                    }
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Unable to get running tasks", e);
+                    isBackgroundAuth = true;
+                }
+            }
+
+            // Fail authentication if we can't confirm the client activity is on top.
+            if (isBackgroundAuth) {
+                Slog.e(TAG, "Failing possible background authentication");
+                authenticated = false;
+
+                // SafetyNet logging for exploitation attempts of b/159249069.
+                final ApplicationInfo appInfo = getContext().getApplicationInfo();
+                EventLog.writeEvent(0x534e4554, "159249069", appInfo != null ? appInfo.uid : -1,
+                        "Attempted background authentication");
+            }
+
             if (authenticated) {
+                // SafetyNet logging for b/159249069 if constraint is violated.
+                if (isBackgroundAuth) {
+                    final ApplicationInfo appInfo = getContext().getApplicationInfo();
+                    EventLog.writeEvent(0x534e4554, "159249069", appInfo != null ? appInfo.uid : -1,
+                            "Successful background authentication!");
+                }
+
                 mAlreadyDone = true;
 
                 if (listener != null) {
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 347beab..bcb17bc 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -1601,7 +1601,7 @@
      */
     public synchronized void onUserStopped() {
         // Switch off networking lockdown (if it was enabled)
-        setLockdown(false);
+        setVpnForcedLocked(false);
         mAlwaysOn = false;
 
         // Quit any active connections
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 69b02ce..f630820 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -113,6 +113,7 @@
 import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.internal.util.Preconditions;
 import com.android.internal.widget.ICheckCredentialProgressCallback;
 import com.android.internal.widget.ILockSettings;
 import com.android.internal.widget.LockPatternUtils;
@@ -2618,6 +2619,10 @@
     protected AuthenticationToken initializeSyntheticPasswordLocked(byte[] credentialHash,
             LockscreenCredential credential, int userId) {
         Slog.i(TAG, "Initialize SyntheticPassword for user: " + userId);
+        Preconditions.checkState(
+                getSyntheticPasswordHandleLocked(userId) == SyntheticPasswordManager.DEFAULT_HANDLE,
+                "Cannot reinitialize SP");
+
         final AuthenticationToken auth = mSpManager.newSyntheticPasswordAndSid(
                 getGateKeeperService(), credentialHash, credential, userId);
         if (auth == null) {
@@ -2678,7 +2683,7 @@
 
     @VisibleForTesting
     protected boolean shouldMigrateToSyntheticPasswordLocked(int userId) {
-        return true;
+        return getSyntheticPasswordHandleLocked(userId) == SyntheticPasswordManager.DEFAULT_HANDLE;
     }
 
     private VerifyCredentialResponse spBasedDoVerifyCredential(LockscreenCredential userCredential,
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
index 8eefd8f..a106dc6 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
@@ -115,7 +115,7 @@
     private static final String TAG = "UriGrantsManagerService";
     // Maximum number of persisted Uri grants a package is allowed
     private static final int MAX_PERSISTED_URI_GRANTS = 512;
-    private static final boolean ENABLE_DYNAMIC_PERMISSIONS = false;
+    private static final boolean ENABLE_DYNAMIC_PERMISSIONS = true;
 
     private final Object mLock = new Object();
     private final H mH;
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index ba85199..2c2fdca 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -519,10 +519,24 @@
         LockscreenCredential password = newPassword("password");
         initializeCredentialUnderSP(password, PRIMARY_USER_ID);
         assertTrue(mService.setLockCredential(password, password, PRIMARY_USER_ID));
+        assertNoOrphanedFilesLeft(PRIMARY_USER_ID);
+    }
 
+    @Test
+    public void testAddingEscrowToken_NoOrphanedFilesLeft() throws Exception {
+        final byte[] token = "some-high-entropy-secure-token".getBytes();
+        for (int i = 0; i < 16; i++) {
+            long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
+            assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+            mLocalService.removeEscrowToken(handle, PRIMARY_USER_ID);
+        }
+        assertNoOrphanedFilesLeft(PRIMARY_USER_ID);
+    }
+
+    private void assertNoOrphanedFilesLeft(int userId) {
         String handleString = String.format("%016x",
-                mService.getSyntheticPasswordHandleLocked(PRIMARY_USER_ID));
-        File directory = mStorage.getSyntheticPasswordDirectoryForUser(PRIMARY_USER_ID);
+                mService.getSyntheticPasswordHandleLocked(userId));
+        File directory = mStorage.getSyntheticPasswordDirectoryForUser(userId);
         for (File file : directory.listFiles()) {
             String[] parts = file.getName().split("\\.");
             if (!parts[0].equals(handleString) && !parts[0].equals("0000000000000000")) {