Merge "Merge "Merge "IMS: Propagate media profile changed message" am: 7ae295368d" into stage-aosp-master am: f520199452 am: a8ead38883"
diff --git a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
index e4ce62d..4a1e5b9 100644
--- a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
+++ b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
@@ -23,9 +23,9 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.content.pm.SigningInfo;
import android.os.Build;
@@ -49,9 +49,8 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Set;
-
import java.util.Objects;
+import java.util.Set;
/**
* We back up the signatures of each package so that during a system restore,
@@ -95,6 +94,7 @@
// is coming from pre-Android P device.
private static final int UNDEFINED_ANCESTRAL_RECORD_VERSION = -1;
+ private int mUserId;
private List<PackageInfo> mAllPackages;
private PackageManager mPackageManager;
// version & signature info of each app in a restore set
@@ -129,17 +129,18 @@
// We're constructed with the set of applications that are participating
// in backup. This set changes as apps are installed & removed.
- public PackageManagerBackupAgent(PackageManager packageMgr, List<PackageInfo> packages) {
- init(packageMgr, packages);
+ public PackageManagerBackupAgent(
+ PackageManager packageMgr, List<PackageInfo> packages, int userId) {
+ init(packageMgr, packages, userId);
}
- public PackageManagerBackupAgent(PackageManager packageMgr) {
- init(packageMgr, null);
+ public PackageManagerBackupAgent(PackageManager packageMgr, int userId) {
+ init(packageMgr, null, userId);
evaluateStorablePackages();
}
- private void init(PackageManager packageMgr, List<PackageInfo> packages) {
+ private void init(PackageManager packageMgr, List<PackageInfo> packages, int userId) {
mPackageManager = packageMgr;
mAllPackages = packages;
mRestoredSignatures = null;
@@ -147,17 +148,19 @@
mStoredSdkVersion = Build.VERSION.SDK_INT;
mStoredIncrementalVersion = Build.VERSION.INCREMENTAL;
+ mUserId = userId;
}
// We will need to refresh our understanding of what is eligible for
// backup periodically; this entry point serves that purpose.
public void evaluateStorablePackages() {
- mAllPackages = getStorableApplications(mPackageManager);
+ mAllPackages = getStorableApplications(mPackageManager, mUserId);
}
- public static List<PackageInfo> getStorableApplications(PackageManager pm) {
- List<PackageInfo> pkgs;
- pkgs = pm.getInstalledPackages(PackageManager.GET_SIGNING_CERTIFICATES);
+ /** Gets all packages installed on user {@code userId} eligible for backup. */
+ public static List<PackageInfo> getStorableApplications(PackageManager pm, int userId) {
+ List<PackageInfo> pkgs =
+ pm.getInstalledPackagesAsUser(PackageManager.GET_SIGNING_CERTIFICATES, userId);
int N = pkgs.size();
for (int a = N-1; a >= 0; a--) {
PackageInfo pkg = pkgs.get(a);
@@ -237,8 +240,8 @@
ComponentName home = getPreferredHomeComponent();
if (home != null) {
try {
- homeInfo = mPackageManager.getPackageInfo(home.getPackageName(),
- PackageManager.GET_SIGNING_CERTIFICATES);
+ homeInfo = mPackageManager.getPackageInfoAsUser(home.getPackageName(),
+ PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
homeInstaller = mPackageManager.getInstallerPackageName(home.getPackageName());
homeVersion = homeInfo.getLongVersionCode();
SigningInfo signingInfo = homeInfo.signingInfo;
@@ -315,8 +318,8 @@
} else {
PackageInfo info = null;
try {
- info = mPackageManager.getPackageInfo(packName,
- PackageManager.GET_SIGNING_CERTIFICATES);
+ info = mPackageManager.getPackageInfoAsUser(packName,
+ PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
} catch (NameNotFoundException e) {
// Weird; we just found it, and now are told it doesn't exist.
// Treat it as having been removed from the device.
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index ed6a46c..0412b0f 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -496,11 +496,18 @@
mBaseStateDir = checkNotNull(baseStateDir, "baseStateDir cannot be null");
mBaseStateDir.mkdirs();
if (!SELinux.restorecon(mBaseStateDir)) {
- Slog.e(TAG, "SELinux restorecon failed on " + mBaseStateDir);
+ Slog.w(TAG, "SELinux restorecon failed on " + mBaseStateDir);
}
mDataDir = checkNotNull(dataDir, "dataDir cannot be null");
-
+ // TODO(b/120424138): Remove when the system user moves out of the cache dir. The cache dir
+ // is managed by init.rc so we don't have to create it below.
+ if (userId != UserHandle.USER_SYSTEM) {
+ mDataDir.mkdirs();
+ if (!SELinux.restorecon(mDataDir)) {
+ Slog.w(TAG, "SELinux restorecon failed on " + mDataDir);
+ }
+ }
mBackupPasswordManager = new BackupPasswordManager(mContext, mBaseStateDir, mRng);
// Receivers for scheduled backups and transport initialization operations.
@@ -797,7 +804,7 @@
* non-lifecycle agent instance, so we manually set up the context topology for it.
*/
public BackupAgent makeMetadataAgent() {
- PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(mPackageManager);
+ PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(mPackageManager, mUserId);
pmAgent.attach(mContext);
pmAgent.onCreate();
return pmAgent;
@@ -808,7 +815,7 @@
*/
public PackageManagerBackupAgent makeMetadataAgent(List<PackageInfo> packages) {
PackageManagerBackupAgent pmAgent =
- new PackageManagerBackupAgent(mPackageManager, packages);
+ new PackageManagerBackupAgent(mPackageManager, packages, mUserId);
pmAgent.attach(mContext);
pmAgent.onCreate();
return pmAgent;
@@ -879,7 +886,7 @@
boolean changed = false;
ArrayList<FullBackupEntry> schedule = null;
List<PackageInfo> apps =
- PackageManagerBackupAgent.getStorableApplications(mPackageManager);
+ PackageManagerBackupAgent.getStorableApplications(mPackageManager, mUserId);
if (mFullBackupScheduleFile.exists()) {
try (FileInputStream fstream = new FileInputStream(mFullBackupScheduleFile);
@@ -1428,8 +1435,7 @@
mConnecting = true;
mConnectedAgent = null;
try {
- if (mActivityManager.bindBackupAgent(app.packageName, mode,
- UserHandle.USER_OWNER)) {
+ if (mActivityManager.bindBackupAgent(app.packageName, mode, mUserId)) {
Slog.d(TAG, "awaiting agent for " + app);
// success; wait for the agent to arrive
@@ -1488,7 +1494,7 @@
public void clearApplicationDataSynchronous(String packageName, boolean keepSystemState) {
// Don't wipe packages marked allowClearUserData=false
try {
- PackageInfo info = mPackageManager.getPackageInfo(packageName, 0);
+ PackageInfo info = mPackageManager.getPackageInfoAsUser(packageName, 0, mUserId);
if ((info.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) == 0) {
if (MORE_DEBUG) {
Slog.i(TAG, "allowClearUserData=false so not wiping "
@@ -1507,7 +1513,7 @@
mClearingData = true;
try {
mActivityManager.clearApplicationUserData(
- packageName, keepSystemState, observer, 0);
+ packageName, keepSystemState, observer, mUserId);
} catch (RemoteException e) {
// can't happen because the activity manager is in this process
}
@@ -1616,8 +1622,8 @@
continue;
}
try {
- PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName,
- PackageManager.GET_SIGNING_CERTIFICATES);
+ PackageInfo packageInfo = mPackageManager.getPackageInfoAsUser(packageName,
+ PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
if (!AppBackupUtils.appIsEligibleForBackup(packageInfo.applicationInfo,
mPackageManager)) {
BackupObserverUtils.sendBackupOnPackageResult(observer, packageName,
@@ -2339,8 +2345,8 @@
if (DEBUG) Slog.v(TAG, "clearBackupData() of " + packageName + " on " + transportName);
PackageInfo info;
try {
- info = mPackageManager.getPackageInfo(packageName,
- PackageManager.GET_SIGNING_CERTIFICATES);
+ info = mPackageManager.getPackageInfoAsUser(packageName,
+ PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
} catch (NameNotFoundException e) {
Slog.d(TAG, "No such package '" + packageName + "' - not clearing backup data");
return;
@@ -3258,7 +3264,7 @@
if (packageName != null) {
PackageInfo app = null;
try {
- app = mPackageManager.getPackageInfo(packageName, 0);
+ app = mPackageManager.getPackageInfoAsUser(packageName, 0, mUserId);
} catch (NameNotFoundException nnf) {
Slog.w(TAG, "Asked to restore nonexistent pkg " + packageName);
throw new IllegalArgumentException("Package " + packageName + " not found");
@@ -3362,7 +3368,7 @@
mTransportManager.getCurrentTransportClient(callerLogString);
boolean eligible =
AppBackupUtils.appIsRunningAndEligibleForBackupWithTransport(
- transportClient, packageName, mPackageManager);
+ transportClient, packageName, mPackageManager, mUserId);
if (transportClient != null) {
mTransportManager.disposeOfTransportClient(transportClient, callerLogString);
}
@@ -3386,7 +3392,7 @@
for (String packageName : packages) {
if (AppBackupUtils
.appIsRunningAndEligibleForBackupWithTransport(
- transportClient, packageName, mPackageManager)) {
+ transportClient, packageName, mPackageManager, mUserId)) {
eligibleApps.add(packageName);
}
}
diff --git a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
index ef7ff92..862ca71 100644
--- a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
+++ b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
@@ -45,7 +45,6 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.SELinux;
-import android.os.UserHandle;
import android.os.WorkSource;
import com.android.internal.annotations.GuardedBy;
@@ -241,6 +240,7 @@
private final boolean mUserInitiated;
private final boolean mNonIncremental;
private final int mCurrentOpToken;
+ private final int mUserId;
private final File mStateDirectory;
private final File mDataDirectory;
private final File mBlankStateFile;
@@ -320,6 +320,7 @@
mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
mQueueLock = mBackupManagerService.getQueueLock();
mBlankStateFile = new File(mStateDirectory, BLANK_STATE_FILE_NAME);
+ mUserId = backupManagerService.getUserId();
}
private void registerTask() {
@@ -480,8 +481,8 @@
final PackageInfo packageInfo;
try {
packageInfo =
- mPackageManager.getPackageInfo(
- packageName, PackageManager.GET_SIGNING_CERTIFICATES);
+ mPackageManager.getPackageInfoAsUser(
+ packageName, PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
} catch (PackageManager.NameNotFoundException e) {
mReporter.onAgentUnknown(packageName);
throw AgentException.permanent(e);
@@ -770,8 +771,7 @@
private void writeWidgetPayloadIfAppropriate(FileDescriptor fd, String pkgName)
throws IOException {
- // TODO: http://b/22388012
- byte[] widgetState = AppWidgetBackupBridge.getWidgetState(pkgName, UserHandle.USER_SYSTEM);
+ byte[] widgetState = AppWidgetBackupBridge.getWidgetState(pkgName, mUserId);
File widgetFile = new File(mStateDirectory, pkgName + "_widget");
boolean priorStateExists = widgetFile.exists();
if (!priorStateExists && widgetState == null) {
diff --git a/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java b/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java
index e273b32..0fa0f89 100644
--- a/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java
+++ b/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java
@@ -54,6 +54,7 @@
private final TransportManager mTransportManager;
private final String mTransportName;
private final UserBackupManagerService mBackupManagerService;
+ private final int mUserId;
@Nullable private final String mPackageName;
public RestoreSet[] mRestoreSets = null;
boolean mEnded = false;
@@ -67,6 +68,7 @@
mPackageName = packageName;
mTransportManager = backupManagerService.getTransportManager();
mTransportName = transportName;
+ mUserId = backupManagerService.getUserId();
}
public void markTimedOut() {
@@ -304,7 +306,8 @@
final PackageInfo app;
try {
- app = mBackupManagerService.getPackageManager().getPackageInfo(packageName, 0);
+ app = mBackupManagerService.getPackageManager().getPackageInfoAsUser(
+ packageName, 0, mUserId);
} catch (NameNotFoundException nnf) {
Slog.w(TAG, "Asked to restore nonexistent pkg " + packageName);
return -1;
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index 45a398f..c7f3315 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -272,7 +272,7 @@
instream, mBackupManagerService.getContext(),
mDeleteObserver, mManifestSignatures,
mPackagePolicies, info, installerPackageName,
- bytesReadListener);
+ bytesReadListener, mBackupManagerService.getUserId());
// good to go; promote to ACCEPT
mPackagePolicies.put(pkg, isSuccessfullyInstalled
? RestorePolicy.ACCEPT
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index f7efad6..5284d94 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -48,7 +48,6 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
-import android.os.UserHandle;
import android.util.EventLog;
import android.util.Slog;
@@ -81,6 +80,7 @@
public class PerformUnifiedRestoreTask implements BackupRestoreTask {
private UserBackupManagerService backupManagerService;
+ private final int mUserId;
private final TransportManager mTransportManager;
// Transport client we're working with to do the restore
private final TransportClient mTransportClient;
@@ -175,6 +175,7 @@
@Nullable String[] filterSet,
OnTaskFinishedListener listener) {
this.backupManagerService = backupManagerService;
+ mUserId = backupManagerService.getUserId();
mTransportManager = backupManagerService.getTransportManager();
mEphemeralOpToken = backupManagerService.generateRandomIntegerToken();
mState = UnifiedRestoreState.INITIAL;
@@ -204,7 +205,7 @@
// We want everything and a pony
List<PackageInfo> apps =
PackageManagerBackupAgent.getStorableApplications(
- backupManagerService.getPackageManager());
+ backupManagerService.getPackageManager(), mUserId);
filterSet = packagesToNames(apps);
if (DEBUG) {
Slog.i(TAG, "Full restore; asking about " + filterSet.length + " apps");
@@ -221,7 +222,7 @@
for (int i = 0; i < filterSet.length; i++) {
try {
PackageManager pm = backupManagerService.getPackageManager();
- PackageInfo info = pm.getPackageInfo(filterSet[i], 0);
+ PackageInfo info = pm.getPackageInfoAsUser(filterSet[i], 0, mUserId);
if ("android".equals(info.packageName)) {
hasSystem = true;
continue;
@@ -240,16 +241,16 @@
}
if (hasSystem) {
try {
- mAcceptSet.add(0,
- backupManagerService.getPackageManager().getPackageInfo("android", 0));
+ mAcceptSet.add(0, backupManagerService.getPackageManager().getPackageInfoAsUser(
+ "android", 0, mUserId));
} catch (NameNotFoundException e) {
// won't happen; we know a priori that it's valid
}
}
if (hasSettings) {
try {
- mAcceptSet.add(backupManagerService.getPackageManager().getPackageInfo(
- SETTINGS_PACKAGE, 0));
+ mAcceptSet.add(backupManagerService.getPackageManager().getPackageInfoAsUser(
+ SETTINGS_PACKAGE, 0, mUserId));
} catch (NameNotFoundException e) {
// this one is always valid too
}
@@ -360,7 +361,7 @@
// If we're starting a full-system restore, set up to begin widget ID remapping
if (mIsSystemRestore) {
// TODO: http://b/22388012
- AppWidgetBackupBridge.restoreStarting(UserHandle.USER_SYSTEM);
+ AppWidgetBackupBridge.restoreStarting(mUserId);
}
try {
@@ -508,8 +509,8 @@
}
try {
- mCurrentPackage = backupManagerService.getPackageManager().getPackageInfo(
- pkgName, PackageManager.GET_SIGNING_CERTIFICATES);
+ mCurrentPackage = backupManagerService.getPackageManager().getPackageInfoAsUser(
+ pkgName, PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
} catch (NameNotFoundException e) {
// Whoops, we thought we could restore this package but it
// turns out not to be present. Skip it.
@@ -1079,7 +1080,7 @@
// Kick off any work that may be needed regarding app widget restores
// TODO: http://b/22388012
- AppWidgetBackupBridge.restoreFinished(UserHandle.USER_SYSTEM);
+ AppWidgetBackupBridge.restoreFinished(mUserId);
// If this was a full-system restore, record the ancestral
// dataset information
diff --git a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
index e465c7e..054879b 100644
--- a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
@@ -91,10 +91,13 @@
* </ol>
*/
public static boolean appIsRunningAndEligibleForBackupWithTransport(
- @Nullable TransportClient transportClient, String packageName, PackageManager pm) {
+ @Nullable TransportClient transportClient,
+ String packageName,
+ PackageManager pm,
+ int userId) {
try {
- PackageInfo packageInfo = pm.getPackageInfo(packageName,
- PackageManager.GET_SIGNING_CERTIFICATES);
+ PackageInfo packageInfo = pm.getPackageInfoAsUser(packageName,
+ PackageManager.GET_SIGNING_CERTIFICATES, userId);
ApplicationInfo applicationInfo = packageInfo.applicationInfo;
if (!appIsEligibleForBackup(applicationInfo, pm)
|| appIsStopped(applicationInfo)
diff --git a/services/backup/java/com/android/server/backup/utils/RestoreUtils.java b/services/backup/java/com/android/server/backup/utils/RestoreUtils.java
index df7e6d4..cce5b3b 100644
--- a/services/backup/java/com/android/server/backup/utils/RestoreUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/RestoreUtils.java
@@ -72,7 +72,9 @@
HashMap<String, Signature[]> manifestSignatures,
HashMap<String, RestorePolicy> packagePolicies,
FileMetadata info,
- String installerPackageName, BytesReadListener bytesReadListener) {
+ String installerPackageName,
+ BytesReadListener bytesReadListener,
+ int userId) {
boolean okay = true;
if (DEBUG) {
@@ -144,8 +146,8 @@
uninstall = true;
} else {
try {
- PackageInfo pkg = packageManager.getPackageInfo(info.packageName,
- PackageManager.GET_SIGNING_CERTIFICATES);
+ PackageInfo pkg = packageManager.getPackageInfoAsUser(info.packageName,
+ PackageManager.GET_SIGNING_CERTIFICATES, userId);
if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP)
== 0) {
Slog.w(TAG, "Restore stream contains apk of package "
diff --git a/services/core/java/com/android/server/slice/SlicePermissionManager.java b/services/core/java/com/android/server/slice/SlicePermissionManager.java
index 315d5e3..1d1c28f 100644
--- a/services/core/java/com/android/server/slice/SlicePermissionManager.java
+++ b/services/core/java/com/android/server/slice/SlicePermissionManager.java
@@ -175,18 +175,24 @@
handlePersist();
}
for (String file : new File(mSliceDir.getAbsolutePath()).list()) {
- if (file.isEmpty()) continue;
try (ParserHolder parser = getParser(file)) {
- Persistable p;
- while (parser.parser.getEventType() != XmlPullParser.START_TAG) {
+ Persistable p = null;
+ while (parser.parser.getEventType() != XmlPullParser.END_DOCUMENT) {
+ if (parser.parser.getEventType() == XmlPullParser.START_TAG) {
+ if (SliceClientPermissions.TAG_CLIENT.equals(parser.parser.getName())) {
+ p = SliceClientPermissions.createFrom(parser.parser, tracker);
+ } else {
+ p = SliceProviderPermissions.createFrom(parser.parser, tracker);
+ }
+ break;
+ }
parser.parser.next();
}
- if (SliceClientPermissions.TAG_CLIENT.equals(parser.parser.getName())) {
- p = SliceClientPermissions.createFrom(parser.parser, tracker);
+ if (p != null) {
+ p.writeTo(out);
} else {
- p = SliceProviderPermissions.createFrom(parser.parser, tracker);
+ Slog.w(TAG, "Invalid or empty slice permissions file: " + file);
}
- p.writeTo(out);
}
}
diff --git a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java
index 0d3b6b2..b8db3f3 100644
--- a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java
@@ -46,6 +46,7 @@
import android.util.SparseArray;
import com.android.server.backup.testing.TransportData;
+import com.android.server.testing.shadows.ShadowApplicationPackageManager;
import com.android.server.testing.shadows.ShadowBinder;
import org.junit.After;
@@ -65,7 +66,7 @@
/** Tests for the user-aware backup/restore system service {@link BackupManagerService}. */
@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowBinder.class})
+@Config(shadows = {ShadowApplicationPackageManager.class, ShadowBinder.class})
@Presubmit
public class BackupManagerServiceTest {
private static final String TEST_PACKAGE = "package";
diff --git a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java
index 4968176..3b7fa3d 100644
--- a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java
@@ -42,6 +42,8 @@
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.os.Binder;
import android.os.HandlerThread;
import android.os.PowerManager;
@@ -54,6 +56,7 @@
import com.android.server.backup.testing.TransportTestUtils.TransportMock;
import com.android.server.backup.transport.TransportNotRegisteredException;
import com.android.server.testing.shadows.ShadowAppBackupUtils;
+import com.android.server.testing.shadows.ShadowApplicationPackageManager;
import com.android.server.testing.shadows.ShadowBinder;
import com.android.server.testing.shadows.ShadowKeyValueBackupJob;
import com.android.server.testing.shadows.ShadowKeyValueBackupTask;
@@ -80,7 +83,7 @@
* UserBackupManagerService} that performs operations for its target user.
*/
@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowAppBackupUtils.class})
+@Config(shadows = {ShadowAppBackupUtils.class, ShadowApplicationPackageManager.class})
@Presubmit
public class UserBackupManagerServiceTest {
private static final String TAG = "BMSTest";
@@ -137,6 +140,7 @@
public void tearDown() throws Exception {
mBackupThread.quit();
ShadowAppBackupUtils.reset();
+ ShadowApplicationPackageManager.reset();
}
/**
@@ -195,6 +199,7 @@
public void testIsAppEligibleForBackup_whenAppNotEligible() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
setUpCurrentTransport(mTransportManager, mTransport);
+ registerPackages(PACKAGE_1);
UserBackupManagerService backupManagerService = createUserBackupManagerServiceAndRunTasks();
boolean result = backupManagerService.isAppEligibleForBackup(PACKAGE_1);
@@ -210,6 +215,7 @@
public void testIsAppEligibleForBackup_whenAppEligible() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
TransportMock transportMock = setUpCurrentTransport(mTransportManager, backupTransport());
+ registerPackages(PACKAGE_1);
ShadowAppBackupUtils.setAppRunningAndEligibleForBackupWithTransport(PACKAGE_1);
UserBackupManagerService backupManagerService = createUserBackupManagerServiceAndRunTasks();
@@ -228,6 +234,7 @@
public void testIsAppEligibleForBackup_withoutPermission() throws Exception {
mShadowContext.denyPermissions(android.Manifest.permission.BACKUP);
setUpCurrentTransport(mTransportManager, mTransport);
+ registerPackages(PACKAGE_1);
ShadowAppBackupUtils.setAppRunningAndEligibleForBackupWithTransport(PACKAGE_1);
UserBackupManagerService backupManagerService = createUserBackupManagerServiceAndRunTasks();
@@ -245,6 +252,7 @@
public void testFilterAppsEligibleForBackup() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
TransportMock transportMock = setUpCurrentTransport(mTransportManager, mTransport);
+ registerPackages(PACKAGE_1, PACKAGE_2);
ShadowAppBackupUtils.setAppRunningAndEligibleForBackupWithTransport(PACKAGE_1);
UserBackupManagerService backupManagerService = createUserBackupManagerServiceAndRunTasks();
@@ -264,6 +272,7 @@
@Test
public void testFilterAppsEligibleForBackup_whenNoneIsEligible() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
+ registerPackages(PACKAGE_1, PACKAGE_2);
UserBackupManagerService backupManagerService = createUserBackupManagerServiceAndRunTasks();
String[] filtered =
@@ -281,6 +290,7 @@
public void testFilterAppsEligibleForBackup_withoutPermission() throws Exception {
mShadowContext.denyPermissions(android.Manifest.permission.BACKUP);
setUpCurrentTransport(mTransportManager, mTransport);
+ registerPackages(PACKAGE_1, PACKAGE_2);
UserBackupManagerService backupManagerService = createUserBackupManagerServiceAndRunTasks();
expectThrows(
@@ -749,7 +759,7 @@
private void setUpForRequestBackup(String... packages) throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
for (String packageName : packages) {
- mShadowPackageManager.addPackage(packageName);
+ registerPackages(packageName);
ShadowAppBackupUtils.setAppRunningAndEligibleForBackupWithTransport(packageName);
}
setUpCurrentTransport(mTransportManager, mTransport);
@@ -864,7 +874,7 @@
@Test
public void testRequestBackup_whenAppNotEligibleForBackup() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
- mShadowPackageManager.addPackage(PACKAGE_1);
+ registerPackages(PACKAGE_1);
setUpCurrentTransport(mTransportManager, mTransport);
UserBackupManagerService backupManagerService = createUserBackupManagerServiceAndRunTasks();
backupManagerService.setEnabled(true);
@@ -1127,6 +1137,22 @@
backupManagerService.setPowerManager(powerManagerMock);
}
+ private PackageInfo getPackageInfo(String packageName) {
+ PackageInfo packageInfo = new PackageInfo();
+ packageInfo.packageName = packageName;
+ packageInfo.applicationInfo = new ApplicationInfo();
+ packageInfo.applicationInfo.packageName = packageName;
+ return packageInfo;
+ }
+
+ private void registerPackages(String... packages) {
+ for (String packageName : packages) {
+ PackageInfo packageInfo = getPackageInfo(packageName);
+ mShadowPackageManager.installPackage(packageInfo);
+ ShadowApplicationPackageManager.addInstalledPackage(packageName, packageInfo);
+ }
+ }
+
/**
* We can't mock the void method {@link #schedule(Context, long, BackupManagerConstants)} so we
* extend {@link ShadowKeyValueBackupJob} and throw an exception at the end of the method.
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 b08ae6d..bfb2b14 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
@@ -29,6 +29,7 @@
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;
import org.junit.Test;
@@ -37,6 +38,7 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
import java.io.File;
@@ -45,6 +47,7 @@
* UserBackupManagerService}.
*/
@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowApplicationPackageManager.class})
@Presubmit
public class SetupObserverTest {
private static final String TAG = "SetupObserverTest";
diff --git a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
index b923bb0..4811523 100644
--- a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
@@ -71,7 +71,6 @@
import android.annotation.Nullable;
import android.app.Application;
-import android.app.ApplicationPackageManager;
import android.app.IBackupAgent;
import android.app.backup.BackupAgent;
import android.app.backup.BackupDataInput;
@@ -116,6 +115,7 @@
import com.android.server.backup.testing.TransportTestUtils;
import com.android.server.backup.testing.TransportTestUtils.TransportMock;
import com.android.server.testing.shadows.FrameworkShadowLooper;
+import com.android.server.testing.shadows.ShadowApplicationPackageManager;
import com.android.server.testing.shadows.ShadowBackupDataInput;
import com.android.server.testing.shadows.ShadowBackupDataOutput;
import com.android.server.testing.shadows.ShadowEventLog;
@@ -135,8 +135,6 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import org.robolectric.annotation.Implements;
-import org.robolectric.annotation.Resetter;
import org.robolectric.shadows.ShadowLooper;
import org.robolectric.shadows.ShadowPackageManager;
import org.robolectric.shadows.ShadowQueuedWork;
@@ -160,7 +158,7 @@
@Config(
shadows = {
FrameworkShadowLooper.class,
- KeyValueBackupTaskTest.ShadowApplicationPackageManager.class,
+ ShadowApplicationPackageManager.class,
ShadowBackupDataInput.class,
ShadowBackupDataOutput.class,
ShadowEventLog.class,
@@ -2437,11 +2435,12 @@
private AgentMock setUpAgent(PackageData packageData) {
try {
+ String packageName = packageData.packageName;
mPackageManager.setApplicationEnabledSetting(
- packageData.packageName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
+ packageName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
PackageInfo packageInfo = getPackageInfo(packageData);
mShadowPackageManager.installPackage(packageInfo);
- ShadowApplicationPackageManager.setPackageInfo(packageInfo);
+ ShadowApplicationPackageManager.addInstalledPackage(packageName, packageInfo);
mContext.sendBroadcast(getPackageAddedIntent(packageData));
// Run the backup looper because on the receiver we post MSG_SCHEDULE_BACKUP_PACKAGE
mShadowBackupLooper.runToEndOfTasks();
@@ -2537,7 +2536,7 @@
private PackageManagerBackupAgent createPmAgent() {
PackageManagerBackupAgent pmAgent =
- new PackageManagerBackupAgent(mApplication.getPackageManager());
+ new PackageManagerBackupAgent(mApplication.getPackageManager(), USER_ID);
pmAgent.attach(mApplication);
pmAgent.onCreate();
return pmAgent;
@@ -2842,7 +2841,7 @@
ThrowingPackageManagerBackupAgent(
PackageManager packageManager, RuntimeException exception) {
- super(packageManager);
+ super(packageManager, USER_ID);
mException = exception;
}
@@ -2854,29 +2853,4 @@
throw mException;
}
}
-
- /**
- * Extends {@link org.robolectric.shadows.ShadowApplicationPackageManager} to return the correct
- * package in user-specific invocations.
- */
- @Implements(value = ApplicationPackageManager.class)
- public static class ShadowApplicationPackageManager
- extends org.robolectric.shadows.ShadowApplicationPackageManager {
- private static PackageInfo sPackageInfo;
-
- static void setPackageInfo(PackageInfo packageInfo) {
- sPackageInfo = packageInfo;
- }
-
- @Override
- protected PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId) {
- return sPackageInfo;
- }
-
- /** Clear {@link #sPackageInfo}. */
- @Resetter
- public static void reset() {
- sPackageInfo = null;
- }
- }
}
diff --git a/services/robotests/backup/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java b/services/robotests/backup/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java
index 4009876..f17a9fe 100644
--- a/services/robotests/backup/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java
@@ -57,6 +57,7 @@
import com.android.server.backup.testing.TransportData;
import com.android.server.backup.testing.TransportTestUtils;
import com.android.server.backup.testing.TransportTestUtils.TransportMock;
+import com.android.server.testing.shadows.ShadowApplicationPackageManager;
import com.android.server.testing.shadows.ShadowEventLog;
import com.android.server.testing.shadows.ShadowPerformUnifiedRestoreTask;
@@ -77,7 +78,13 @@
import java.util.ArrayDeque;
@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowEventLog.class, ShadowPerformUnifiedRestoreTask.class, ShadowBinder.class})
+@Config(
+ shadows = {
+ ShadowApplicationPackageManager.class,
+ ShadowBinder.class,
+ ShadowEventLog.class,
+ ShadowPerformUnifiedRestoreTask.class
+ })
@Presubmit
public class ActiveRestoreSessionTest {
private static final String PACKAGE_1 = "com.example.package1";
@@ -140,6 +147,7 @@
@After
public void tearDown() throws Exception {
+ ShadowApplicationPackageManager.reset();
ShadowPerformUnifiedRestoreTask.reset();
}
@@ -561,7 +569,8 @@
packageInfo.packageName = packageName;
packageInfo.applicationInfo = new ApplicationInfo();
packageInfo.applicationInfo.uid = uid;
- mShadowPackageManager.addPackage(packageInfo);
+ mShadowPackageManager.installPackage(packageInfo);
+ ShadowApplicationPackageManager.addInstalledPackage(packageName, packageInfo);
}
private IRestoreSession createActiveRestoreSession(
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowAppBackupUtils.java b/services/robotests/src/com/android/server/testing/shadows/ShadowAppBackupUtils.java
index 5fffb14..aefc871 100644
--- a/services/robotests/src/com/android/server/testing/shadows/ShadowAppBackupUtils.java
+++ b/services/robotests/src/com/android/server/testing/shadows/ShadowAppBackupUtils.java
@@ -54,7 +54,10 @@
@Implementation
protected static boolean appIsRunningAndEligibleForBackupWithTransport(
- @Nullable TransportClient transportClient, String packageName, PackageManager pm) {
+ @Nullable TransportClient transportClient,
+ String packageName,
+ PackageManager pm,
+ int userId) {
return sAppsRunningAndEligibleForBackupWithTransport.contains(packageName);
}
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java b/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java
new file mode 100644
index 0000000..dc32209
--- /dev/null
+++ b/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2019 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 com.android.server.testing.shadows;
+
+import static android.content.pm.PackageManager.NameNotFoundException;
+
+import android.app.ApplicationPackageManager;
+import android.content.pm.PackageInfo;
+import android.util.ArrayMap;
+
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Extends {@link org.robolectric.shadows.ShadowApplicationPackageManager} to return the correct
+ * package in user-specific invocations.
+ */
+@Implements(value = ApplicationPackageManager.class)
+public class ShadowApplicationPackageManager
+ extends org.robolectric.shadows.ShadowApplicationPackageManager {
+ private static final Map<String, PackageInfo> sPackageInfos = new ArrayMap<>();
+ private static final List<PackageInfo> sInstalledPackages = new ArrayList<>();
+
+ /**
+ * Registers the package {@code packageName} to be returned when invoking {@link
+ * ApplicationPackageManager#getPackageInfoAsUser(String, int, int)} and {@link
+ * ApplicationPackageManager#getInstalledPackagesAsUser(int, int)}.
+ */
+ public static void addInstalledPackage(String packageName, PackageInfo packageInfo) {
+ sPackageInfos.put(packageName, packageInfo);
+ sInstalledPackages.add(packageInfo);
+ }
+
+ @Override
+ protected PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
+ throws NameNotFoundException {
+ if (!sPackageInfos.containsKey(packageName)) {
+ throw new NameNotFoundException(packageName);
+ }
+ return sPackageInfos.get(packageName);
+ }
+
+ @Override
+ protected List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
+ return sInstalledPackages;
+ }
+
+ /** Clear package state. */
+ @Resetter
+ public static void reset() {
+ sPackageInfos.clear();
+ sInstalledPackages.clear();
+ org.robolectric.shadows.ShadowApplicationPackageManager.reset();
+ }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java
index b315e51..efefee1 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java
@@ -16,6 +16,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import android.content.ContentProvider;
import android.content.ContentResolver;
@@ -26,6 +27,7 @@
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
+import android.util.Log;
import android.util.Xml.Encoding;
import com.android.server.UiServiceTestCase;
@@ -46,10 +48,12 @@
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
public class SlicePermissionManagerTest extends UiServiceTestCase {
+ private static final String TAG = "SlicePerManTest";
@Test
public void testGrant() {
- File sliceDir = new File(mContext.getDataDir(), "system/slices");
+ File sliceDir = new File(mContext.getCacheDir(), "testGrantSlices");
+ Log.v(TAG, "testGrant: slice permissions stored in " + sliceDir.getAbsolutePath());
SlicePermissionManager permissions = new SlicePermissionManager(mContext,
TestableLooper.get(this).getLooper(), sliceDir);
Uri uri = new Builder().scheme(ContentResolver.SCHEME_CONTENT)
@@ -59,11 +63,15 @@
permissions.grantSliceAccess("my.pkg", 0, "provider.pkg", 0, uri);
assertTrue(permissions.hasPermission("my.pkg", 0, uri));
+
+ // Cleanup.
+ assertTrue(FileUtils.deleteContentsAndDir(sliceDir));
}
@Test
public void testBackup() throws XmlPullParserException, IOException {
- File sliceDir = new File(mContext.getDataDir(), "system/slices");
+ File sliceDir = new File(mContext.getCacheDir(), "testBackupSlices");
+ Log.v(TAG, "testBackup: slice permissions stored in " + sliceDir.getAbsolutePath());
Uri uri = new Builder().scheme(ContentResolver.SCHEME_CONTENT)
.authority("authority")
.path("something").build();
@@ -90,7 +98,10 @@
TestableLooper.get(this).getLooper());
permissions.readRestore(parser);
- assertTrue(permissions.hasFullAccess("com.android.mypkg", 10));
+ if (!permissions.hasFullAccess("com.android.mypkg", 10)) {
+ fail("com.android.mypkg@10 did not have full access. backup file: "
+ + output.toString());
+ }
assertTrue(permissions.hasPermission("com.android.otherpkg", 0,
ContentProvider.maybeAddUserId(uri, 1)));
permissions.removePkg("com.android.lastpkg", 1);
@@ -102,8 +113,9 @@
}
@Test
- public void testInvalid() throws Exception {
- File sliceDir = new File(mContext.getCacheDir(), "slices-test");
+ public void testInvalid() {
+ File sliceDir = new File(mContext.getCacheDir(), "testInvalidSlices");
+ Log.v(TAG, "testInvalid: slice permissions stored in " + sliceDir.getAbsolutePath());
if (!sliceDir.exists()) {
sliceDir.mkdir();
}
@@ -118,7 +130,8 @@
@Override
public void writeTo(XmlSerializer out) throws IOException {
- throw new RuntimeException("this doesn't work");
+ throw new RuntimeException("this RuntimeException inside junk.writeTo() "
+ + "should be caught and suppressed by surrounding code");
}
};