Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 53cf5208 authored by Annie Meng's avatar Annie Meng
Browse files

[Multi-user] Convert various calls to use user id

Changes various transport, restore and general bookkeeping flows. Also
performs restorecon recursively to relabel child directories properly.

Bug: 121198605
Bug: 121197942
Bug: 121198606
Test: 1) atest RunBackupFrameworksServicesRoboTests
2) user unlocked -> transports registered successfully
3) adb shell bmgr backupnow [package]
4) Cloud restore backup set from 3) -> apps + widgets successful
5) atest BackupManagerTransportAttributesHostSideTest
6) Add secondary user -> check all directories/files relabelled
Change-Id: I26b23fd7bf10b792658fa7c44941be50aee65521
parent f8e7ff91
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -562,7 +562,7 @@ public class TransportManager {
    private void registerTransportsFromPackage(
            String packageName, Predicate<ComponentName> 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");
+9 −24
Original line number Diff line number Diff line
@@ -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<PackageInfo> allAgentPackages() {
        // !!! TODO: cache this and regenerate only when necessary
        int flags = PackageManager.GET_SIGNING_CERTIFICATES;
        List<PackageInfo> packages = mPackageManager.getInstalledPackages(flags);
        List<PackageInfo> 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<String> 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");
            }
+7 −5
Original line number Diff line number Diff line
@@ -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;
        }
+0 −2
Original line number Diff line number Diff line
@@ -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
+12 −1
Original line number Diff line number Diff line
@@ -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(
Loading