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

Commit 807128ea authored by Amith Yamasani's avatar Amith Yamasani
Browse files

Allow any user's UsageStats to be backed up and restored

Refactor update mappings jobs and prune jobs to use the
user id as the job id and use job namespaces.

Plumb the userId through from the system backup agent

Put 0 in the userId field of the payload to ensure that it
can restore on a single-user device even if backed up from
a secondary user. Henceforth the userId in the payload should
be ignored

Test: Unlock user and dumpsys jobscheduler to look for update job
      Uninstall an app and look for prune job
      Manually force a backup from HSUM device main user and
      restore the dataset on a non-HSUM device

Bug: 260831016

Change-Id: I64904664eb0c949415a9a05eb919674d74081aba
parent dc0f1da4
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -123,6 +123,9 @@ public final class UserHandle implements Parcelable {
    @TestApi
    public static final int MIN_SECONDARY_USER_ID = 10;

    /** @hide */
    public static final int MAX_SECONDARY_USER_ID = Integer.MAX_VALUE / UserHandle.PER_USER_RANGE;

    /**
     * (Arbitrary) user handle cache size.
     * {@link #CACHED_USER_HANDLES} caches user handles in the range of
+2 −2
Original line number Diff line number Diff line
@@ -329,11 +329,11 @@ public abstract class UsageStatsManagerInternal {
     * when the user is first unlocked to update the usage stats package mappings data that might
     * be stale or have existed from a restore and belongs to packages that are not installed for
     * this user anymore.
     * Note: this is only executed for the system user.
     *
     * @param userId The user to update
     * @return {@code true} if the updating was successful, {@code false} otherwise
     */
    public abstract boolean updatePackageMappingsData();
    public abstract boolean updatePackageMappingsData(@UserIdInt int userId);

    /**
     * Listener interface for usage events.
+2 −2
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ public class SystemBackupAgent extends BackupAgentHelper {

    private static final Set<String> sEligibleForMultiUser = Sets.newArraySet(
            PERMISSION_HELPER, NOTIFICATION_HELPER, SYNC_SETTINGS_HELPER, APP_LOCALES_HELPER,
            ACCOUNT_MANAGER_HELPER);
            ACCOUNT_MANAGER_HELPER, USAGE_STATS_HELPER);

    private int mUserId = UserHandle.USER_SYSTEM;

@@ -99,7 +99,7 @@ public class SystemBackupAgent extends BackupAgentHelper {
        addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper(mUserId));
        addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(mUserId));
        addHelper(PERMISSION_HELPER, new PermissionBackupHelper(mUserId));
        addHelper(USAGE_STATS_HELPER, new UsageStatsBackupHelper(this));
        addHelper(USAGE_STATS_HELPER, new UsageStatsBackupHelper(mUserId));
        addHelper(SHORTCUT_MANAGER_HELPER, new ShortcutBackupHelper());
        addHelper(ACCOUNT_MANAGER_HELPER, new AccountManagerBackupHelper(mUserId));
        addHelper(SLICES_HELPER, new SliceBackupHelper(this));
+16 −6
Original line number Diff line number Diff line
package com.android.server.backup;


import android.annotation.UserIdInt;
import android.app.backup.BlobBackupHelper;
import android.app.usage.UsageStatsManagerInternal;
import android.content.Context;
import android.os.UserHandle;
import android.util.Log;

@@ -26,8 +26,16 @@ public class UsageStatsBackupHelper extends BlobBackupHelper {
    // same as UsageStatsDatabase.KEY_USAGE_STATS
    static final String KEY_USAGE_STATS = "usage_stats";

    public UsageStatsBackupHelper(Context context) {
    private final @UserIdInt int mUserId;

    /**
     * Marshall/unmarshall the usagestats data for the given user
     *
     * @param userId The userId to backup/restore
     */
    public UsageStatsBackupHelper(@UserIdInt int userId) {
        super(BLOB_VERSION, KEY_USAGE_STATS);
        mUserId = userId;
    }

    @Override
@@ -38,8 +46,11 @@ public class UsageStatsBackupHelper extends BlobBackupHelper {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            DataOutputStream out  = new DataOutputStream(baos);
            try {
                // Note: Write 0 here deliberately so that a backup from a secondary user
                // can still be restored to an older OS where the restore was always to user 0
                // Writing the actual userId here would result in restores not working on pre-U.
                out.writeInt(UserHandle.USER_SYSTEM);
                out.write(localUsageStatsManager.getBackupPayload(UserHandle.USER_SYSTEM, key));
                out.write(localUsageStatsManager.getBackupPayload(mUserId, key));
            } catch (IOException ioe) {
                if (DEBUG) Log.e(TAG, "Failed to backup Usage Stats", ioe);
                baos.reset();
@@ -49,7 +60,6 @@ public class UsageStatsBackupHelper extends BlobBackupHelper {
        return null;
    }


    @Override
    protected void applyRestoredPayload(String key, byte[] payload)  {
        if (KEY_USAGE_STATS.equals(key)) {
@@ -57,10 +67,10 @@ public class UsageStatsBackupHelper extends BlobBackupHelper {
                    LocalServices.getService(UsageStatsManagerInternal.class);
            DataInputStream in = new DataInputStream(new ByteArrayInputStream(payload));
            try {
                int user = in.readInt();
                in.readInt(); // Legacy userId parameter, read and ignore
                byte[] restoreData = new byte[payload.length - 4];
                in.read(restoreData, 0, restoreData.length);
                localUsageStatsManager.applyRestoredPayload(user, key, restoreData);
                localUsageStatsManager.applyRestoredPayload(mUserId, key, restoreData);
            } catch (IOException ioe) {
                if (DEBUG) Log.e(TAG, "Failed to restore Usage Stats", ioe);
            }
+1 −1
Original line number Diff line number Diff line
@@ -261,7 +261,7 @@ public class UserManagerService extends IUserManager.Stub {

    // We need to keep process uid within Integer.MAX_VALUE.
    @VisibleForTesting
    static final int MAX_USER_ID = Integer.MAX_VALUE / UserHandle.PER_USER_RANGE;
    static final int MAX_USER_ID = UserHandle.MAX_SECONDARY_USER_ID;

    // Max size of the queue of recently removed users
    @VisibleForTesting
Loading