Merge "Specify status results for RollbackManager.commitRollback."
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 9bcb36f..4491b95 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -3017,6 +3017,15 @@
     }
 
     @Override
+    public String getContentCaptureServicePackageName() {
+        try {
+            return mPM.getContentCaptureServicePackageName();
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    @Override
     public boolean isPackageStateProtected(String packageName, int userId) {
         try {
             return mPM.isPackageStateProtected(packageName, userId);
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 4b130b2..7bd8c4e 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -686,6 +686,8 @@
 
     String getWellbeingPackageName();
 
+    String getContentCaptureServicePackageName();
+
     boolean isPackageStateProtected(String packageName, int userId);
 
     void sendDeviceCustomizationReadyBroadcast();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 783ee64..0aa33c8 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -6734,6 +6734,16 @@
     }
 
     /**
+     * @return the system defined content capture service package name, or null if there's none.
+     *
+     * @hide
+     */
+    public String getContentCaptureServicePackageName() {
+        throw new UnsupportedOperationException(
+                "getContentCaptureServicePackageName not implemented in subclass");
+    }
+
+    /**
      * @return whether a given package's state is protected, e.g. package cannot be disabled,
      *         suspended, hidden or force stopped.
      *
diff --git a/core/java/android/content/pm/TEST_MAPPING b/core/java/android/content/pm/TEST_MAPPING
new file mode 100644
index 0000000..a2e98cc
--- /dev/null
+++ b/core/java/android/content/pm/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "imports": [
+    {
+      "path": "system/apex/tests"
+    }
+  ]
+}
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index cc22ff0..85f1159 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -73,6 +73,7 @@
 
 static void getPosTextPath(const SkFont& font, const uint16_t glyphs[], int count,
                            const SkPoint pos[], SkPath* dst) {
+    dst->reset();
     struct Rec {
         SkPath* fDst;
         const SkPoint* fPos;
diff --git a/services/backup/java/com/android/server/backup/FullBackupJob.java b/services/backup/java/com/android/server/backup/FullBackupJob.java
index 33d21cb0..f62a875 100644
--- a/services/backup/java/com/android/server/backup/FullBackupJob.java
+++ b/services/backup/java/com/android/server/backup/FullBackupJob.java
@@ -32,9 +32,9 @@
     private static final String USER_ID_EXTRA_KEY = "userId";
 
     @VisibleForTesting
-    static final int MIN_JOB_ID = 52418896;
+    public static final int MIN_JOB_ID = 52418896;
     @VisibleForTesting
-    static final int MAX_JOB_ID = 52419896;
+    public static final int MAX_JOB_ID = 52419896;
 
     private static ComponentName sIdleService =
             new ComponentName("android", FullBackupJob.class.getName());
diff --git a/services/backup/java/com/android/server/backup/KeyValueBackupJob.java b/services/backup/java/com/android/server/backup/KeyValueBackupJob.java
index d43859e..72d81d3 100644
--- a/services/backup/java/com/android/server/backup/KeyValueBackupJob.java
+++ b/services/backup/java/com/android/server/backup/KeyValueBackupJob.java
@@ -58,8 +58,10 @@
     @GuardedBy("KeyValueBackupJob.class")
     private static final SparseLongArray sNextScheduledForUserId = new SparseLongArray();
 
-    private static final int MIN_JOB_ID = 52417896;
-    private static final int MAX_JOB_ID = 52418896;
+    @VisibleForTesting
+    public static final int MIN_JOB_ID = 52417896;
+    @VisibleForTesting
+    public static final int MAX_JOB_ID = 52418896;
 
     public static void schedule(int userId, Context ctx, BackupManagerConstants constants) {
         schedule(userId, ctx, 0, constants);
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 115e924..7d228f1 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -1906,13 +1906,7 @@
                 final long interval = mConstants.getFullBackupIntervalMilliseconds();
                 final long appLatency = (timeSinceLast < interval) ? (interval - timeSinceLast) : 0;
                 final long latency = Math.max(transportMinLatency, appLatency);
-                Runnable r = new Runnable() {
-                    @Override
-                    public void run() {
-                        FullBackupJob.schedule(mUserId, mContext, latency, mConstants);
-                    }
-                };
-                mBackupHandler.postDelayed(r, 2500);
+                FullBackupJob.schedule(mUserId, mContext, latency, mConstants);
             } else {
                 if (DEBUG_SCHEDULING) {
                     Slog.i(TAG, "Full backup queue empty; not scheduling");
@@ -2144,12 +2138,7 @@
                     Slog.i(TAG, "Nothing pending full backup; rescheduling +" + latency);
                 }
                 final long deferTime = latency;     // pin for the closure
-                mBackupHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        FullBackupJob.schedule(mUserId, mContext, deferTime, mConstants);
-                    }
-                });
+                FullBackupJob.schedule(mUserId, mContext, deferTime, mConstants);
                 return false;
             }
 
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 1369f7b..238eed4 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -770,7 +770,10 @@
                                 action.isContextual() ? 1 : 0)
                         .addTaggedData(
                                 MetricsEvent.NOTIFICATION_SMART_SUGGESTION_ASSISTANT_GENERATED,
-                                generatedByAssistant ? 1 : 0));
+                                generatedByAssistant ? 1 : 0)
+                        .addTaggedData(MetricsEvent.NOTIFICATION_LOCATION,
+                                nv.location.toMetricsEventEnum()));
+
                 EventLogTags.writeNotificationActionClicked(key, actionIndex,
                         r.getLifespanMs(now), r.getFreshnessMs(now), r.getExposureMs(now),
                         nv.rank, nv.count);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 6eff815..265d07a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -42,7 +42,6 @@
 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
-import static android.content.pm.PackageManager.INSTALL_ALLOW_DOWNGRADE;
 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
@@ -202,8 +201,8 @@
 import android.content.pm.dex.ArtManager;
 import android.content.pm.dex.DexMetadataHelper;
 import android.content.pm.dex.IArtManager;
-import android.content.rollback.IRollbackManager;
 import android.content.res.Resources;
+import android.content.rollback.IRollbackManager;
 import android.database.ContentObserver;
 import android.graphics.Bitmap;
 import android.hardware.display.DisplayManager;
@@ -20096,6 +20095,24 @@
     }
 
     @Override
+    public String getContentCaptureServicePackageName() {
+        String contentCaptureServiceName =
+                mContext.getString(R.string.config_defaultContentCaptureService);
+
+        if (TextUtils.isEmpty(contentCaptureServiceName)) {
+            return null;
+        }
+
+        int separatorIndex = contentCaptureServiceName.indexOf("/");
+
+        if (separatorIndex < 0) {
+            return null;
+        }
+
+        return contentCaptureServiceName.substring(0, separatorIndex);
+    }
+
+    @Override
     public void setApplicationEnabledSetting(String appPackageName,
             int newState, int flags, int userId, String callingPackage) {
         if (!sUserManager.exists(userId)) return;
diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
new file mode 100644
index 0000000..a2e98cc
--- /dev/null
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "imports": [
+    {
+      "path": "system/apex/tests"
+    }
+  ]
+}
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 20d6d4e..bfa539c 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -737,6 +737,14 @@
         grantSystemFixedPermissionsToSystemPackage("com.android.sharedstoragebackup", userId,
                 STORAGE_PERMISSIONS);
 
+        // Content Capture Service
+        String contentCaptureServicePackageName =
+                mContext.getPackageManager().getContentCaptureServicePackageName();
+        if (!TextUtils.isEmpty(contentCaptureServicePackageName)) {
+            grantPermissionsToSystemPackage(contentCaptureServicePackageName, userId,
+                    MICROPHONE_PERMISSIONS);
+        }
+
         if (mPermissionGrantedCallback != null) {
             mPermissionGrantedCallback.onDefaultRuntimePermissionsGranted(userId);
         }
diff --git a/services/robotests/backup/src/com/android/server/backup/internal/SetupObserverTest.java b/services/robotests/backup/src/com/android/server/backup/internal/SetupObserverTest.java
index bfb2b14..44e9e6a 100644
--- a/services/robotests/backup/src/com/android/server/backup/internal/SetupObserverTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/internal/SetupObserverTest.java
@@ -18,17 +18,19 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.app.job.JobScheduler;
 import android.content.Context;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.platform.test.annotations.Presubmit;
 import android.provider.Settings;
 
+import com.android.server.backup.FullBackupJob;
+import com.android.server.backup.JobIdManager;
 import com.android.server.backup.KeyValueBackupJob;
 import com.android.server.backup.TransportManager;
 import com.android.server.backup.UserBackupManagerService;
 import com.android.server.backup.testing.BackupManagerServiceTestUtils;
-import com.android.server.backup.testing.TestUtils;
 import com.android.server.testing.shadows.ShadowApplicationPackageManager;
 
 import org.junit.Before;
@@ -38,7 +40,9 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.Shadows;
 import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowJobScheduler;
 
 import java.io.File;
 
@@ -47,7 +51,7 @@
  * UserBackupManagerService}.
  */
 @RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowApplicationPackageManager.class})
+@Config(shadows = {ShadowApplicationPackageManager.class, ShadowJobScheduler.class})
 @Presubmit
 public class SetupObserverTest {
     private static final String TAG = "SetupObserverTest";
@@ -58,6 +62,7 @@
     private Context mContext;
     private UserBackupManagerService mUserBackupManagerService;
     private HandlerThread mHandlerThread;
+    private ShadowJobScheduler mShadowJobScheduler;
 
     /** Setup state. */
     @Before
@@ -73,6 +78,7 @@
                         new File(mContext.getDataDir(), "test1"),
                         new File(mContext.getDataDir(), "test2"),
                         mTransportManager);
+        mShadowJobScheduler = Shadows.shadowOf(mContext.getSystemService(JobScheduler.class));
     }
 
     /** Test observer handles changes from not setup -> setup correctly. */
@@ -121,17 +127,27 @@
         // Setup conditions for a full backup job to be scheduled.
         mUserBackupManagerService.setEnabled(true);
         mUserBackupManagerService.enqueueFullBackup("testPackage", /* lastBackedUp */ 0);
-        // Clear the handler of all pending tasks. This is to prevent the below assertion on the
-        // handler from encountering false positives due to other tasks being scheduled as part of
-        // setup work.
-        TestUtils.runToEndOfTasks(mHandlerThread.getLooper());
 
         setupObserver.onChange(true);
 
-        assertThat(KeyValueBackupJob.isScheduled(mUserBackupManagerService.getUserId())).isTrue();
-        // Verifies that the full backup job is scheduled. The job is scheduled via a posted message
-        // on the backup handler so we verify that a message exists.
-        assertThat(mUserBackupManagerService.getBackupHandler().hasMessagesOrCallbacks()).isTrue();
+        assertThat(
+                        mShadowJobScheduler.getPendingJob(
+                                getJobIdForUser(
+                                        KeyValueBackupJob.MIN_JOB_ID,
+                                        KeyValueBackupJob.MAX_JOB_ID,
+                                        USER_ID)))
+                .isNotNull();
+        assertThat(
+                        mShadowJobScheduler.getPendingJob(
+                                getJobIdForUser(
+                                        FullBackupJob.MIN_JOB_ID,
+                                        FullBackupJob.MAX_JOB_ID,
+                                        USER_ID)))
+                .isNotNull();
+    }
+
+    private int getJobIdForUser(int min, int max, int userId) {
+        return JobIdManager.getJobIdForUserId(min, max, userId);
     }
 
     private void changeSetupCompleteSettingForUser(boolean value, int userId) {
diff --git a/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java b/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java
index 095a1de..5b02266 100644
--- a/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java
+++ b/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java
@@ -51,6 +51,7 @@
 import android.os.IBinder;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
+
 import java.util.List;
 
 /**
@@ -1146,6 +1147,11 @@
     }
 
     @Override
+    public String getContentCaptureServicePackageName() throws RemoteException {
+        return null;
+    }
+
+    @Override
     public boolean isPackageStateProtected(String packageName, int userId) throws RemoteException {
         return false;
     }