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

Commit c8c3329d authored by Makoto Onuki's avatar Makoto Onuki
Browse files

Don't update publisher version code without scanning manifest

- It was (theoretically) possible for shortcut manager to update
the version code for a publisher package without rescanning manifest
shortcuts, if backup happens right after unlocking a user before
SM searches for updated packages.  If it happens, then SM will not
scan the manifest for this package until it's updated next time.

So don't refresh the version code during backup, which we only
have to do for launchers but not publishers.

- Also fix the owner-user-id for launchers.  (Luckily it's not causing
any issues.)

Bug 31402152

Change-Id: I5d898eb3882b74edaca8b2d5f960849370ffc23b
parent 6c3f26e5
Loading
Loading
Loading
Loading
+12 −1
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@ package com.android.server.pm;


import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.annotation.UserIdInt;
import android.content.pm.PackageInfo;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutInfo;
import android.util.ArrayMap;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.ArraySet;
@@ -151,6 +152,16 @@ class ShortcutLauncher extends ShortcutPackageItem {
        return mPinnedShortcuts.remove(PackageWithUser.of(packageUserId, packageName)) != null;
        return mPinnedShortcuts.remove(PackageWithUser.of(packageUserId, packageName)) != null;
    }
    }


    public void ensureVersionInfo() {
        final PackageInfo pi = mShortcutUser.mService.getPackageInfoWithSignatures(
                getPackageName(), getPackageUserId());
        if (pi == null) {
            Slog.w(TAG, "Package not found: " + getPackageName());
            return;
        }
        getPackageInfo().updateVersionInfo(pi);
    }

    /**
    /**
     * Persist.
     * Persist.
     */
     */
@@ -202,7 +213,7 @@ class ShortcutLauncher extends ShortcutPackageItem {
                fromBackup ? ownerUserId
                fromBackup ? ownerUserId
                : ShortcutService.parseIntAttribute(parser, ATTR_LAUNCHER_USER_ID, ownerUserId);
                : ShortcutService.parseIntAttribute(parser, ATTR_LAUNCHER_USER_ID, ownerUserId);


        final ShortcutLauncher ret = new ShortcutLauncher(shortcutUser, launcherUserId,
        final ShortcutLauncher ret = new ShortcutLauncher(shortcutUser, ownerUserId,
                launcherPackageName, launcherUserId);
                launcherPackageName, launcherUserId);


        ArraySet<String> ids = null;
        ArraySet<String> ids = null;
+0 −27
Original line number Original line Diff line number Diff line
@@ -23,7 +23,6 @@ import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInfo;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutInfo;
import android.content.res.Resources;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.PersistableBundle;
import android.text.format.Formatter;
import android.text.format.Formatter;
import android.util.ArrayMap;
import android.util.ArrayMap;
@@ -145,30 +144,6 @@ class ShortcutPackage extends ShortcutPackageItem {
        return mPackageUid;
        return mPackageUid;
    }
    }


    /**
     * Called when a shortcut is about to be published.  At this point we know the publisher
     * package
     * exists (as opposed to Launcher trying to fetch shortcuts from a non-existent package), so
     * we do some initialization for the package.
     */
    private void ensurePackageVersionInfo() {
        // Make sure we have the version code for the app.  We need the version code in
        // handlePackageUpdated().
        if (getPackageInfo().getVersionCode() < 0) {
            final ShortcutService s = mShortcutUser.mService;

            final PackageInfo pi = s.getPackageInfo(getPackageName(), getOwnerUserId());
            if (pi != null) {
                if (ShortcutService.DEBUG) {
                    Slog.d(TAG, String.format("Package %s version = %d", getPackageName(),
                            pi.versionCode));
                }
                getPackageInfo().updateVersionInfo(pi);
                s.scheduleSaveUser(getOwnerUserId());
            }
        }
    }

    @Nullable
    @Nullable
    public Resources getPackageResources() {
    public Resources getPackageResources() {
        return mShortcutUser.mService.injectGetResourcesForApplicationAsUser(
        return mShortcutUser.mService.injectGetResourcesForApplicationAsUser(
@@ -251,8 +226,6 @@ class ShortcutPackage extends ShortcutPackageItem {
        Preconditions.checkArgument(newShortcut.isEnabled(),
        Preconditions.checkArgument(newShortcut.isEnabled(),
                "add/setDynamicShortcuts() cannot publish disabled shortcuts");
                "add/setDynamicShortcuts() cannot publish disabled shortcuts");


        ensurePackageVersionInfo();

        newShortcut.addFlags(ShortcutInfo.FLAG_DYNAMIC);
        newShortcut.addFlags(ShortcutInfo.FLAG_DYNAMIC);


        final ShortcutInfo oldShortcut = mShortcuts.get(newShortcut.getId());
        final ShortcutInfo oldShortcut = mShortcuts.get(newShortcut.getId());
+5 −4
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.UserIdInt;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInfo;
import android.util.Slog;
import android.util.Slog;


import com.android.internal.annotations.VisibleForTesting;
import com.android.server.backup.BackupUtils;
import com.android.server.backup.BackupUtils;


import libcore.io.Base64;
import libcore.io.Base64;
@@ -89,6 +90,7 @@ class ShortcutPackageInfo {
        return mLastUpdateTime;
        return mLastUpdateTime;
    }
    }


    /** Set {@link #mVersionCode} and {@link #mLastUpdateTime} from a {@link PackageInfo}. */
    public void updateVersionInfo(@NonNull PackageInfo pi) {
    public void updateVersionInfo(@NonNull PackageInfo pi) {
        if (pi != null) {
        if (pi != null) {
            mVersionCode = pi.versionCode;
            mVersionCode = pi.versionCode;
@@ -119,7 +121,8 @@ class ShortcutPackageInfo {
        return true;
        return true;
    }
    }


    public static ShortcutPackageInfo generateForInstalledPackage(
    @VisibleForTesting
    public static ShortcutPackageInfo generateForInstalledPackageForTest(
            ShortcutService s, String packageName, @UserIdInt int packageUserId) {
            ShortcutService s, String packageName, @UserIdInt int packageUserId) {
        final PackageInfo pi = s.getPackageInfoWithSignatures(packageName, packageUserId);
        final PackageInfo pi = s.getPackageInfoWithSignatures(packageName, packageUserId);
        if (pi.signatures == null || pi.signatures.length == 0) {
        if (pi.signatures == null || pi.signatures.length == 0) {
@@ -132,7 +135,7 @@ class ShortcutPackageInfo {
        return ret;
        return ret;
    }
    }


    public void refresh(ShortcutService s, ShortcutPackageItem pkg) {
    public void refreshSignature(ShortcutService s, ShortcutPackageItem pkg) {
        if (mIsShadow) {
        if (mIsShadow) {
            s.wtf("Attempted to refresh package info for shadow package " + pkg.getPackageName()
            s.wtf("Attempted to refresh package info for shadow package " + pkg.getPackageName()
                    + ", user=" + pkg.getOwnerUserId());
                    + ", user=" + pkg.getOwnerUserId());
@@ -145,8 +148,6 @@ class ShortcutPackageInfo {
            Slog.w(TAG, "Package not found: " + pkg.getPackageName());
            Slog.w(TAG, "Package not found: " + pkg.getPackageName());
            return;
            return;
        }
        }
        mVersionCode = pi.versionCode;
        mLastUpdateTime = pi.lastUpdateTime;
        mSigHashes = BackupUtils.hashSignatureArray(pi.signatures);
        mSigHashes = BackupUtils.hashSignatureArray(pi.signatures);
    }
    }


+3 −4
Original line number Original line Diff line number Diff line
@@ -65,8 +65,7 @@ abstract class ShortcutPackageItem {
    /**
    /**
     * ID of the user who actually has this package running on.  For {@link ShortcutPackage},
     * ID of the user who actually has this package running on.  For {@link ShortcutPackage},
     * this is the same thing as {@link #getOwnerUserId}, but if it's a {@link ShortcutLauncher} and
     * this is the same thing as {@link #getOwnerUserId}, but if it's a {@link ShortcutLauncher} and
     * {@link #getOwnerUserId} is of a work profile, then this ID could be the user who owns the
     * {@link #getOwnerUserId} is of work profile, then this ID is of the primary user.
     * profile.
     */
     */
    public int getPackageUserId() {
    public int getPackageUserId() {
        return mPackageUserId;
        return mPackageUserId;
@@ -86,12 +85,12 @@ abstract class ShortcutPackageItem {
        return mPackageInfo;
        return mPackageInfo;
    }
    }


    public void refreshPackageInfoAndSave() {
    public void refreshPackageSignatureAndSave() {
        if (mPackageInfo.isShadow()) {
        if (mPackageInfo.isShadow()) {
            return; // Don't refresh for shadow user.
            return; // Don't refresh for shadow user.
        }
        }
        final ShortcutService s = mShortcutUser.mService;
        final ShortcutService s = mShortcutUser.mService;
        mPackageInfo.refresh(s, this);
        mPackageInfo.refreshSignature(s, this);
        s.scheduleSaveUser(getOwnerUserId());
        s.scheduleSaveUser(getOwnerUserId());
    }
    }


+36 −23
Original line number Original line Diff line number Diff line
@@ -1158,7 +1158,10 @@ public class ShortcutService extends IShortcutService.Stub {
        }
        }
    }
    }


    /** Return the per-user per-package state. */
    /**
     * Return the per-user per-package state.  If the caller is a publisher, use
     * {@link #getPackageShortcutsForPublisherLocked} instead.
     */
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    @NonNull
    @NonNull
    ShortcutPackage getPackageShortcutsLocked(
    ShortcutPackage getPackageShortcutsLocked(
@@ -1166,6 +1169,16 @@ public class ShortcutService extends IShortcutService.Stub {
        return getUserShortcutsLocked(userId).getPackageShortcuts(packageName);
        return getUserShortcutsLocked(userId).getPackageShortcuts(packageName);
    }
    }


    /** Return the per-user per-package state.  Use this when the caller is a publisher. */
    @GuardedBy("mLock")
    @NonNull
    ShortcutPackage getPackageShortcutsForPublisherLocked(
            @NonNull String packageName, @UserIdInt int userId) {
        final ShortcutPackage ret = getUserShortcutsLocked(userId).getPackageShortcuts(packageName);
        ret.getUser().onCalledByPublisher(packageName);
        return ret;
    }

    @GuardedBy("mLock")
    @GuardedBy("mLock")
    @NonNull
    @NonNull
    ShortcutLauncher getLauncherShortcutsLocked(
    ShortcutLauncher getLauncherShortcutsLocked(
@@ -1634,8 +1647,7 @@ public class ShortcutService extends IShortcutService.Stub {
        synchronized (mLock) {
        synchronized (mLock) {
            throwIfUserLockedL(userId);
            throwIfUserLockedL(userId);


            final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
            final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
            ps.getUser().onCalledByPublisher(packageName);


            ps.ensureImmutableShortcutsNotIncluded(newShortcuts);
            ps.ensureImmutableShortcutsNotIncluded(newShortcuts);


@@ -1686,8 +1698,7 @@ public class ShortcutService extends IShortcutService.Stub {
        synchronized (mLock) {
        synchronized (mLock) {
            throwIfUserLockedL(userId);
            throwIfUserLockedL(userId);


            final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
            final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
            ps.getUser().onCalledByPublisher(packageName);


            ps.ensureImmutableShortcutsNotIncluded(newShortcuts);
            ps.ensureImmutableShortcutsNotIncluded(newShortcuts);


@@ -1767,8 +1778,7 @@ public class ShortcutService extends IShortcutService.Stub {
        synchronized (mLock) {
        synchronized (mLock) {
            throwIfUserLockedL(userId);
            throwIfUserLockedL(userId);


            final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
            final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
            ps.getUser().onCalledByPublisher(packageName);


            ps.ensureImmutableShortcutsNotIncluded(newShortcuts);
            ps.ensureImmutableShortcutsNotIncluded(newShortcuts);


@@ -1817,8 +1827,7 @@ public class ShortcutService extends IShortcutService.Stub {
        synchronized (mLock) {
        synchronized (mLock) {
            throwIfUserLockedL(userId);
            throwIfUserLockedL(userId);


            final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
            final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
            ps.getUser().onCalledByPublisher(packageName);


            ps.ensureImmutableShortcutsNotIncludedWithIds((List<String>) shortcutIds);
            ps.ensureImmutableShortcutsNotIncludedWithIds((List<String>) shortcutIds);


@@ -1847,8 +1856,7 @@ public class ShortcutService extends IShortcutService.Stub {
        synchronized (mLock) {
        synchronized (mLock) {
            throwIfUserLockedL(userId);
            throwIfUserLockedL(userId);


            final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
            final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
            ps.getUser().onCalledByPublisher(packageName);


            ps.ensureImmutableShortcutsNotIncludedWithIds((List<String>) shortcutIds);
            ps.ensureImmutableShortcutsNotIncludedWithIds((List<String>) shortcutIds);


@@ -1870,8 +1878,7 @@ public class ShortcutService extends IShortcutService.Stub {
        synchronized (mLock) {
        synchronized (mLock) {
            throwIfUserLockedL(userId);
            throwIfUserLockedL(userId);


            final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
            final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
            ps.getUser().onCalledByPublisher(packageName);


            ps.ensureImmutableShortcutsNotIncludedWithIds((List<String>) shortcutIds);
            ps.ensureImmutableShortcutsNotIncludedWithIds((List<String>) shortcutIds);


@@ -1895,8 +1902,7 @@ public class ShortcutService extends IShortcutService.Stub {
        synchronized (mLock) {
        synchronized (mLock) {
            throwIfUserLockedL(userId);
            throwIfUserLockedL(userId);


            final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
            final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
            ps.getUser().onCalledByPublisher(packageName);
            ps.deleteAllDynamicShortcuts();
            ps.deleteAllDynamicShortcuts();
        }
        }
        packageShortcutsChanged(packageName, userId);
        packageShortcutsChanged(packageName, userId);
@@ -1951,8 +1957,7 @@ public class ShortcutService extends IShortcutService.Stub {


        final ArrayList<ShortcutInfo> ret = new ArrayList<>();
        final ArrayList<ShortcutInfo> ret = new ArrayList<>();


        final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
        final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
        ps.getUser().onCalledByPublisher(packageName);
        ps.findAll(ret, query, cloneFlags);
        ps.findAll(ret, query, cloneFlags);


        return new ParceledListSlice<>(ret);
        return new ParceledListSlice<>(ret);
@@ -1973,8 +1978,7 @@ public class ShortcutService extends IShortcutService.Stub {
        synchronized (mLock) {
        synchronized (mLock) {
            throwIfUserLockedL(userId);
            throwIfUserLockedL(userId);


            final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
            final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
            ps.getUser().onCalledByPublisher(packageName);
            return mMaxUpdatesPerInterval - ps.getApiCallCount();
            return mMaxUpdatesPerInterval - ps.getApiCallCount();
        }
        }
    }
    }
@@ -2013,8 +2017,7 @@ public class ShortcutService extends IShortcutService.Stub {
        synchronized (mLock) {
        synchronized (mLock) {
            throwIfUserLockedL(userId);
            throwIfUserLockedL(userId);


            final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
            final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
            ps.getUser().onCalledByPublisher(packageName);


            if (ps.findShortcutById(shortcutId) == null) {
            if (ps.findShortcutById(shortcutId) == null) {
                Log.w(TAG, String.format("reportShortcutUsed: package %s doesn't have shortcut %s",
                Log.w(TAG, String.format("reportShortcutUsed: package %s doesn't have shortcut %s",
@@ -3151,9 +3154,19 @@ public class ShortcutService extends IShortcutService.Stub {
                return null;
                return null;
            }
            }


            user.forAllPackageItems(spi -> spi.refreshPackageInfoAndSave());
            // Update the signatures for all packages.
            user.forAllPackageItems(spi -> spi.refreshPackageSignatureAndSave());

            // Set the version code for the launchers.
            // We shouldn't do this for publisher packages, because we don't want to update the
            // version code without rescanning the manifest.
            user.forAllLaunchers(launcher -> launcher.ensureVersionInfo());

            // Save to the filesystem.
            scheduleSaveUser(userId);
            saveDirtyInfo();


            // Then save.
            // Then create the backup payload.
            final ByteArrayOutputStream os = new ByteArrayOutputStream(32 * 1024);
            final ByteArrayOutputStream os = new ByteArrayOutputStream(32 * 1024);
            try {
            try {
                saveUserInternalLocked(userId, os, /* forBackup */ true);
                saveUserInternalLocked(userId, os, /* forBackup */ true);
Loading