diff --git a/services/backup/java/com/android/server/backup/TransportManager.java b/services/backup/java/com/android/server/backup/TransportManager.java index 529430ca4eaf8..a7bada07ffa8b 100644 --- a/services/backup/java/com/android/server/backup/TransportManager.java +++ b/services/backup/java/com/android/server/backup/TransportManager.java @@ -562,7 +562,7 @@ public class TransportManager { private void registerTransportsFromPackage( String packageName, Predicate transportComponentFilter) { try { - mPackageManager.getPackageInfo(packageName, 0); + mPackageManager.getPackageInfoAsUser(packageName, 0, mUserId); } catch (PackageManager.NameNotFoundException e) { Slog.e(TAG, "Trying to register transports from package not found " + packageName); return; @@ -599,7 +599,8 @@ public class TransportManager { return false; } try { - PackageInfo packInfo = mPackageManager.getPackageInfo(transport.getPackageName(), 0); + PackageInfo packInfo = + mPackageManager.getPackageInfoAsUser(transport.getPackageName(), 0, mUserId); if ((packInfo.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) == 0) { Slog.w(TAG, "Transport package " + transport.getPackageName() + " not privileged"); diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java index 3a8966a04055a..e0e81ffb6b480 100644 --- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java +++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java @@ -495,7 +495,7 @@ public class UserBackupManagerService { mBaseStateDir = checkNotNull(baseStateDir, "baseStateDir cannot be null"); mBaseStateDir.mkdirs(); - if (!SELinux.restorecon(mBaseStateDir)) { + if (!SELinux.restoreconRecursive(mBaseStateDir)) { Slog.w(TAG, "SELinux restorecon failed on " + mBaseStateDir); } @@ -504,7 +504,7 @@ public class UserBackupManagerService { // 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)) { + if (!SELinux.restoreconRecursive(mDataDir)) { Slog.w(TAG, "SELinux restorecon failed on " + mDataDir); } } @@ -584,7 +584,7 @@ public class UserBackupManagerService { mBackupHandler.postDelayed(this::parseLeftoverJournals, INITIALIZATION_DELAY_MILLIS); // Power management - mWakelock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*backup*"); + mWakelock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*backup*-" + userId); } void initializeBackupEnableState() { @@ -1352,7 +1352,7 @@ public class UserBackupManagerService { private List allAgentPackages() { // !!! TODO: cache this and regenerate only when necessary int flags = PackageManager.GET_SIGNING_CERTIFICATES; - List packages = mPackageManager.getInstalledPackages(flags); + List packages = mPackageManager.getInstalledPackagesAsUser(flags, mUserId); int numPackages = packages.size(); for (int a = numPackages - 1; a >= 0; a--) { PackageInfo pkg = packages.get(a); @@ -1366,8 +1366,8 @@ public class UserBackupManagerService { // we will need the shared library path, so look that up and store it here. // This is used implicitly when we pass the PackageInfo object off to // the Activity Manager to launch the app for backup/restore purposes. - app = mPackageManager.getApplicationInfo(pkg.packageName, - PackageManager.GET_SHARED_LIBRARY_FILES); + app = mPackageManager.getApplicationInfoAsUser(pkg.packageName, + PackageManager.GET_SHARED_LIBRARY_FILES, mUserId); pkg.applicationInfo.sharedLibraryFiles = app.sharedLibraryFiles; pkg.applicationInfo.sharedLibraryInfos = app.sharedLibraryInfos; } @@ -1392,7 +1392,7 @@ public class UserBackupManagerService { notification.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES | Intent.FLAG_RECEIVER_FOREGROUND); notification.putExtra(BACKUP_FINISHED_PACKAGE_EXTRA, packageName); - mContext.sendBroadcastAsUser(notification, UserHandle.OWNER); + mContext.sendBroadcastAsUser(notification, UserHandle.of(mUserId)); } mProcessedPackagesJournal.addPackage(packageName); @@ -2208,11 +2208,10 @@ public class UserBackupManagerService { /** Used by both incremental and full restore to restore widget data. */ public void restoreWidgetData(String packageName, byte[] widgetData) { // Apply the restored widget state and generate the ID update for the app - // TODO: http://b/22388012 if (MORE_DEBUG) { Slog.i(TAG, "Incorporating restored widget data"); } - AppWidgetBackupBridge.restoreWidgetState(packageName, widgetData, UserHandle.USER_SYSTEM); + AppWidgetBackupBridge.restoreWidgetState(packageName, widgetData, mUserId); } // ***************************** @@ -2291,20 +2290,6 @@ public class UserBackupManagerService { /** Sent from an app's backup agent to let the service know that there's new data to backup. */ public void dataChanged(final String packageName) { - final int callingUserHandle = UserHandle.getCallingUserId(); - if (callingUserHandle != UserHandle.USER_SYSTEM) { - // TODO: http://b/22388012 - // App is running under a non-owner user profile. For now, we do not back - // up data from secondary user profiles. - // TODO: backups for all user profiles although don't add backup for profiles - // without adding admin control in DevicePolicyManager. - if (MORE_DEBUG) { - Slog.v(TAG, "dataChanged(" + packageName + ") ignored because it's user " - + callingUserHandle); - } - return; - } - final HashSet targets = dataChangedTargets(packageName); if (targets == null) { Slog.w(TAG, "dataChanged but no participant pkg='" + packageName + "'" @@ -2921,7 +2906,7 @@ public class UserBackupManagerService { try { int transportUid = mContext.getPackageManager() - .getPackageUid(transportComponent.getPackageName(), 0); + .getPackageUidAsUser(transportComponent.getPackageName(), 0, mUserId); if (callingUid != transportUid) { throw new SecurityException("Only the transport can change its description"); } 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 c7f3315493b41..b3d9fbcb88d33 100644 --- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java +++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java @@ -68,6 +68,8 @@ import java.util.List; public class FullRestoreEngine extends RestoreEngine { private final UserBackupManagerService mBackupManagerService; + private final int mUserId; + // Task in charge of monitoring timeouts private final BackupRestoreTask mMonitorTask; @@ -146,6 +148,7 @@ public class FullRestoreEngine extends RestoreEngine { backupManagerService.getAgentTimeoutParameters(), "Timeout parameters cannot be null"); mIsAdbRestore = isAdbRestore; + mUserId = backupManagerService.getUserId(); } public IBackupAgent getAgent() { @@ -272,7 +275,7 @@ public class FullRestoreEngine extends RestoreEngine { instream, mBackupManagerService.getContext(), mDeleteObserver, mManifestSignatures, mPackagePolicies, info, installerPackageName, - bytesReadListener, mBackupManagerService.getUserId()); + bytesReadListener, mUserId); // good to go; promote to ACCEPT mPackagePolicies.put(pkg, isSuccessfullyInstalled ? RestorePolicy.ACCEPT @@ -329,9 +332,8 @@ public class FullRestoreEngine extends RestoreEngine { } try { - mTargetApp = - mBackupManagerService.getPackageManager().getApplicationInfo( - pkg, 0); + mTargetApp = mBackupManagerService.getPackageManager() + .getApplicationInfoAsUser(pkg, 0, mUserId); // If we haven't sent any data to this app yet, we probably // need to clear it first. Check that. @@ -684,7 +686,7 @@ public class FullRestoreEngine extends RestoreEngine { String packageListString = Settings.Secure.getStringForUser( mBackupManagerService.getContext().getContentResolver(), Settings.Secure.PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE, - mBackupManagerService.getUserId()); + mUserId); if (TextUtils.isEmpty(packageListString)) { return false; } 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 5284d94c2aa7a..d01f77bfd84cd 100644 --- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java +++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java @@ -360,7 +360,6 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { // If we're starting a full-system restore, set up to begin widget ID remapping if (mIsSystemRestore) { - // TODO: http://b/22388012 AppWidgetBackupBridge.restoreStarting(mUserId); } @@ -1079,7 +1078,6 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { } // Kick off any work that may be needed regarding app widget restores - // TODO: http://b/22388012 AppWidgetBackupBridge.restoreFinished(mUserId); // If this was a full-system restore, record the ancestral diff --git a/services/robotests/backup/src/com/android/server/backup/TransportManagerTest.java b/services/robotests/backup/src/com/android/server/backup/TransportManagerTest.java index 7559560f4f6d5..9a6e003c13175 100644 --- a/services/robotests/backup/src/com/android/server/backup/TransportManagerTest.java +++ b/services/robotests/backup/src/com/android/server/backup/TransportManagerTest.java @@ -58,7 +58,9 @@ import com.android.server.backup.transport.OnTransportRegisteredListener; import com.android.server.backup.transport.TransportClient; import com.android.server.backup.transport.TransportClientManager; import com.android.server.backup.transport.TransportNotRegisteredException; +import com.android.server.testing.shadows.ShadowApplicationPackageManager; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -66,6 +68,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowPackageManager; import java.util.ArrayList; @@ -75,6 +78,7 @@ import java.util.Set; import java.util.stream.Stream; @RunWith(RobolectricTestRunner.class) +@Config(shadows = {ShadowApplicationPackageManager.class}) @Presubmit public class TransportManagerTest { private static final String PACKAGE_A = "some.package.a"; @@ -102,6 +106,12 @@ public class TransportManagerTest { mTransportB1 = genericTransport(PACKAGE_B, "TransportBaz"); } + /** Reset shadow state. */ + @After + public void tearDown() throws Exception { + ShadowApplicationPackageManager.reset(); + } + @Test public void testRegisterTransports() throws Exception { setUpPackage(PACKAGE_A, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); @@ -666,7 +676,8 @@ public class TransportManagerTest { packageInfo.packageName = packageName; packageInfo.applicationInfo = new ApplicationInfo(); packageInfo.applicationInfo.privateFlags = flags; - mShadowPackageManager.addPackage(packageInfo); + mShadowPackageManager.installPackage(packageInfo); + ShadowApplicationPackageManager.addInstalledPackage(packageName, packageInfo); } private TransportManager createTransportManagerWithRegisteredTransports( 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 3b7fa3d6ed057..427aed7364d2e 100644 --- a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java +++ b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java @@ -514,10 +514,14 @@ public class UserBackupManagerServiceTest { private void setUpForUpdateTransportAttributes() throws Exception { mTransportComponent = mTransport.getTransportComponent(); String transportPackage = mTransportComponent.getPackageName(); + PackageInfo packageInfo = getPackageInfo(transportPackage); ShadowPackageManager shadowPackageManager = shadowOf(mContext.getPackageManager()); - shadowPackageManager.addPackage(transportPackage); + shadowPackageManager.installPackage(packageInfo); shadowPackageManager.setPackagesForUid(PACKAGE_UID, transportPackage); + // Set up for user invocations on ApplicationPackageManager. + ShadowApplicationPackageManager.addInstalledPackage(transportPackage, packageInfo); + ShadowApplicationPackageManager.setPackageUid(transportPackage, PACKAGE_UID); mTransportUid = mContext.getPackageManager().getPackageUid(transportPackage, 0); } diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java b/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java index dc322094add85..ab121eddff060 100644 --- a/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java +++ b/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java @@ -38,6 +38,7 @@ public class ShadowApplicationPackageManager extends org.robolectric.shadows.ShadowApplicationPackageManager { private static final Map sPackageInfos = new ArrayMap<>(); private static final List sInstalledPackages = new ArrayList<>(); + private static final Map sPackageUids = new ArrayMap<>(); /** * Registers the package {@code packageName} to be returned when invoking {@link @@ -49,6 +50,14 @@ public class ShadowApplicationPackageManager sInstalledPackages.add(packageInfo); } + /** + * Sets the package uid {@code packageUid} for the package {@code packageName} to be returned + * when invoking {@link ApplicationPackageManager#getPackageUidAsUser(String, int, int)}. + */ + public static void setPackageUid(String packageName, int packageUid) { + sPackageUids.put(packageName, packageUid); + } + @Override protected PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId) throws NameNotFoundException { @@ -63,6 +72,15 @@ public class ShadowApplicationPackageManager return sInstalledPackages; } + @Override + protected int getPackageUidAsUser(String packageName, int flags, int userId) + throws NameNotFoundException { + if (!sPackageUids.containsKey(packageName)) { + throw new NameNotFoundException(packageName); + } + return sPackageUids.get(packageName); + } + /** Clear package state. */ @Resetter public static void reset() {