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;
}