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

Commit 4fc34416 authored by Makoto Onuki's avatar Makoto Onuki Committed by android-build-merger
Browse files

Merge "ShortcutManager: proper work profile support" into nyc-dev

am: d5b745a9

* commit 'd5b745a9':
  ShortcutManager: proper work profile support

Change-Id: Ic31214205a5a93e37e5585829ae522bf4890b519
parents b33fbc33 d5b745a9
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -47,4 +47,8 @@ interface IShortcutService {
    int getIconMaxDimensions(String packageName, int userId);

    void resetThrottling(); // system only API for developer opsions

    byte[] getBackupPayload(int user);

    void applyRestore(in byte[] payload, int user);
}
 No newline at end of file
+62 −51
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ import java.util.List;
/**
 * Launcher information used by {@link ShortcutService}.
 */
class ShortcutLauncher implements ShortcutPackageItem {
class ShortcutLauncher extends ShortcutPackageItem {
    private static final String TAG = ShortcutService.TAG;

    static final String TAG_ROOT = "launcher-pins";
@@ -44,44 +44,34 @@ class ShortcutLauncher implements ShortcutPackageItem {
    private static final String ATTR_VALUE = "value";
    private static final String ATTR_PACKAGE_NAME = "package-name";

    @UserIdInt
    private final int mUserId;

    @NonNull
    private final String mPackageName;

    @UserIdInt
    private final int mLauncherUserId;
    private final int mOwnerUserId;

    /**
     * Package name -> IDs.
     */
    final private ArrayMap<String, ArraySet<String>> mPinnedShortcuts = new ArrayMap<>();

    ShortcutLauncher(@UserIdInt int userId, @NonNull String packageName,
            @UserIdInt int launcherUserId) {
        mUserId = userId;
        mPackageName = packageName;
        mLauncherUserId = launcherUserId;
    public ShortcutLauncher(@UserIdInt int ownerUserId, @NonNull String packageName,
            @UserIdInt int launcherUserId, ShortcutPackageInfo spi) {
        super(launcherUserId, packageName, spi != null ? spi : ShortcutPackageInfo.newEmpty());
        mOwnerUserId = ownerUserId;
    }

    @UserIdInt
    public int getUserId() {
        return mUserId;
    public ShortcutLauncher(@UserIdInt int ownerUserId, @NonNull String packageName,
            @UserIdInt int launcherUserId) {
        this(launcherUserId, packageName, launcherUserId, null);
    }

    @UserIdInt
    public int getLauncherUserId() {
        return mLauncherUserId;
    @Override
    public int getOwnerUserId() {
        return mOwnerUserId;
    }

    @NonNull
    public String getPackageName() {
        return mPackageName;
    }
    public void pinShortcuts(@NonNull ShortcutService s, @UserIdInt int packageUserId,
            @NonNull String packageName, @NonNull List<String> ids) {
        final ShortcutPackage packageShortcuts =
                s.getPackageShortcutsLocked(packageName, packageUserId);

    public void pinShortcuts(@NonNull ShortcutService s, @NonNull String packageName,
            @NonNull List<String> ids) {
        final int idSize = ids.size();
        if (idSize == 0) {
            mPinnedShortcuts.remove(packageName);
@@ -91,8 +81,6 @@ class ShortcutLauncher implements ShortcutPackageItem {
            // Pin shortcuts.  Make sure only pin the ones that were visible to the caller.
            // i.e. a non-dynamic, pinned shortcut by *other launchers* shouldn't be pinned here.

            final ShortcutPackage packageShortcuts =
                    s.getPackageShortcutsLocked(packageName, mUserId);
            final ArraySet<String> newSet = new ArraySet<>();

            for (int i = 0; i < idSize; i++) {
@@ -107,7 +95,7 @@ class ShortcutLauncher implements ShortcutPackageItem {
            }
            mPinnedShortcuts.put(packageName, newSet);
        }
        s.getPackageShortcutsLocked(packageName, mUserId).refreshPinnedFlags(s);
        packageShortcuts.refreshPinnedFlags(s);
    }

    /**
@@ -124,15 +112,18 @@ class ShortcutLauncher implements ShortcutPackageItem {
    /**
     * Persist.
     */
    public void saveToXml(XmlSerializer out, boolean forBackup) throws IOException {
    @Override
    public void saveToXml(XmlSerializer out, boolean forBackup)
            throws IOException {
        final int size = mPinnedShortcuts.size();
        if (size == 0) {
            return; // Nothing to write.
        }

        out.startTag(null, TAG_ROOT);
        ShortcutService.writeAttr(out, ATTR_PACKAGE_NAME, mPackageName);
        ShortcutService.writeAttr(out, ATTR_LAUNCHER_USER_ID, mLauncherUserId);
        ShortcutService.writeAttr(out, ATTR_PACKAGE_NAME, getPackageName());
        ShortcutService.writeAttr(out, ATTR_LAUNCHER_USER_ID, getPackageUserId());
        getPackageInfo().saveToXml(out);

        for (int i = 0; i < size; i++) {
            out.startTag(null, TAG_PACKAGE);
@@ -153,16 +144,21 @@ class ShortcutLauncher implements ShortcutPackageItem {
    /**
     * Load.
     */
    public static ShortcutLauncher loadFromXml(XmlPullParser parser, int ownerUserId)
            throws IOException, XmlPullParserException {
    public static ShortcutLauncher loadFromXml(XmlPullParser parser, int ownerUserId,
            boolean fromBackup) throws IOException, XmlPullParserException {
        final String launcherPackageName = ShortcutService.parseStringAttribute(parser,
                ATTR_PACKAGE_NAME);
        final int launcherUserId = ShortcutService.parseIntAttribute(parser,
                ATTR_LAUNCHER_USER_ID, ownerUserId);

        // If restoring, just use the real user ID.
        final int launcherUserId =
                fromBackup ? ownerUserId
                : ShortcutService.parseIntAttribute(parser, ATTR_LAUNCHER_USER_ID, ownerUserId);

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

        ShortcutPackageInfo spi = null;

        ArraySet<String> ids = null;
        final int outerDepth = parser.getDepth();
        int type;
@@ -173,7 +169,11 @@ class ShortcutLauncher implements ShortcutPackageItem {
            }
            final int depth = parser.getDepth();
            final String tag = parser.getName();
            if (depth == outerDepth + 1) {
                switch (tag) {
                    case ShortcutPackageInfo.TAG_ROOT:
                        spi = ShortcutPackageInfo.loadFromXml(parser);
                        continue;
                    case TAG_PACKAGE: {
                        final String packageName = ShortcutService.parseStringAttribute(parser,
                                ATTR_PACKAGE_NAME);
@@ -181,13 +181,21 @@ class ShortcutLauncher implements ShortcutPackageItem {
                        ret.mPinnedShortcuts.put(packageName, ids);
                        continue;
                    }
                }
            }
            if (depth == outerDepth + 2) {
                switch (tag) {
                    case TAG_PIN: {
                        ids.add(ShortcutService.parseStringAttribute(parser,
                                ATTR_VALUE));
                        continue;
                    }
                }
            throw ShortcutService.throwForInvalidTag(depth, tag);
            }
            ShortcutService.warnForInvalidTag(depth, tag);
        }
        if (spi != null) {
            ret.replacePackageInfo(spi);
        }
        return ret;
    }
@@ -197,9 +205,12 @@ class ShortcutLauncher implements ShortcutPackageItem {

        pw.print(prefix);
        pw.print("Launcher: ");
        pw.print(mPackageName);
        pw.print("  UserId: ");
        pw.print(mLauncherUserId);
        pw.print(getPackageName());
        pw.print("  Package user: ");
        pw.print(getPackageUserId());
        pw.println();

        getPackageInfo().dump(s, pw, prefix + "  ");
        pw.println();

        final int size = mPinnedShortcuts.size();
+44 −37
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@ package com.android.server.pm;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
@@ -41,7 +40,7 @@ import java.util.function.Predicate;
/**
 * Package information used by {@link ShortcutService}.
 */
class ShortcutPackage implements ShortcutPackageItem {
class ShortcutPackage extends ShortcutPackageItem {
    private static final String TAG = ShortcutService.TAG;

    static final String TAG_ROOT = "package";
@@ -63,12 +62,6 @@ class ShortcutPackage implements ShortcutPackageItem {
    private static final String ATTR_ICON_RES = "icon-res";
    private static final String ATTR_BITMAP_PATH = "bitmap-path";

    @UserIdInt
    private final int mUserId;

    @NonNull
    private final String mPackageName;

    /**
     * All the shortcuts from the package, keyed on IDs.
     */
@@ -89,19 +82,18 @@ class ShortcutPackage implements ShortcutPackageItem {
     */
    private long mLastResetTime;

    ShortcutPackage(int userId, String packageName) {
        mUserId = userId;
        mPackageName = packageName;
    public ShortcutPackage(int packageUserId, String packageName, ShortcutPackageInfo spi) {
        super(packageUserId, packageName, spi != null ? spi : ShortcutPackageInfo.newEmpty());
    }

    @UserIdInt
    public int getUserId() {
        return mUserId;
    public ShortcutPackage(int packageUserId, String packageName) {
        this(packageUserId, packageName, null);
    }

    @NonNull
    public String getPackageName() {
        return mPackageName;
    @Override
    public int getOwnerUserId() {
        // For packages, always owner user == package user.
        return getPackageUserId();
    }

    /**
@@ -116,7 +108,7 @@ class ShortcutPackage implements ShortcutPackageItem {
            @NonNull String id) {
        final ShortcutInfo shortcut = mShortcuts.remove(id);
        if (shortcut != null) {
            s.removeIcon(mUserId, shortcut);
            s.removeIcon(getPackageUserId(), shortcut);
            shortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_PINNED);
        }
        return shortcut;
@@ -124,7 +116,7 @@ class ShortcutPackage implements ShortcutPackageItem {

    void addShortcut(@NonNull ShortcutService s, @NonNull ShortcutInfo newShortcut) {
        deleteShortcut(s, newShortcut.getId());
        s.saveIconAndFixUpShortcut(mUserId, newShortcut);
        s.saveIconAndFixUpShortcut(getPackageUserId(), newShortcut);
        mShortcuts.put(newShortcut.getId(), newShortcut);
    }

@@ -233,11 +225,12 @@ class ShortcutPackage implements ShortcutPackageItem {

        // Then, for the pinned set for each launcher, set the pin flag one by one.
        final ArrayMap<ShortcutUser.PackageWithUser, ShortcutLauncher> launchers =
                s.getUserShortcutsLocked(mUserId).getAllLaunchers();
                s.getUserShortcutsLocked(getPackageUserId()).getAllLaunchers();

        for (int l = launchers.size() - 1; l >= 0; l--) {
            final ShortcutLauncher launcherShortcuts = launchers.valueAt(l);
            final ArraySet<String> pinned = launcherShortcuts.getPinnedShortcutIds(mPackageName);
            final ArraySet<String> pinned = launcherShortcuts.getPinnedShortcutIds(
                    getPackageName());

            if (pinned == null || pinned.size() == 0) {
                continue;
@@ -321,8 +314,8 @@ class ShortcutPackage implements ShortcutPackageItem {

        // Set of pinned shortcuts by the calling launcher.
        final ArraySet<String> pinnedByCallerSet = (callingLauncher == null) ? null
                : s.getLauncherShortcuts(callingLauncher, mUserId, launcherUserId)
                    .getPinnedShortcutIds(mPackageName);
                : s.getLauncherShortcuts(callingLauncher, getPackageUserId(), launcherUserId)
                    .getPinnedShortcutIds(getPackageName());

        for (int i = 0; i < mShortcuts.size(); i++) {
            final ShortcutInfo si = mShortcuts.valueAt(i);
@@ -362,7 +355,7 @@ class ShortcutPackage implements ShortcutPackageItem {

        pw.print(prefix);
        pw.print("Package: ");
        pw.print(mPackageName);
        pw.print(getPackageName());
        pw.println();

        pw.print(prefix);
@@ -380,6 +373,9 @@ class ShortcutPackage implements ShortcutPackageItem {
        pw.print(s.formatTime(mLastResetTime));
        pw.println();

        getPackageInfo().dump(s, pw, prefix + "  ");
        pw.println();

        pw.println("      Shortcuts:");
        long totalBitmapSize = 0;
        final ArrayMap<String, ShortcutInfo> shortcuts = mShortcuts;
@@ -406,6 +402,7 @@ class ShortcutPackage implements ShortcutPackageItem {
        pw.println(")");
    }

    @Override
    public void saveToXml(@NonNull XmlSerializer out, boolean forBackup)
            throws IOException, XmlPullParserException {
        final int size = mShortcuts.size();
@@ -416,10 +413,11 @@ class ShortcutPackage implements ShortcutPackageItem {

        out.startTag(null, TAG_ROOT);

        ShortcutService.writeAttr(out, ATTR_NAME, mPackageName);
        ShortcutService.writeAttr(out, ATTR_NAME, getPackageName());
        ShortcutService.writeAttr(out, ATTR_DYNAMIC_COUNT, mDynamicShortcutCount);
        ShortcutService.writeAttr(out, ATTR_CALL_COUNT, mApiCallCount);
        ShortcutService.writeAttr(out, ATTR_LAST_RESET, mLastResetTime);
        getPackageInfo().saveToXml(out);

        for (int j = 0; j < size; j++) {
            saveShortcut(out, mShortcuts.valueAt(j), forBackup);
@@ -464,13 +462,14 @@ class ShortcutPackage implements ShortcutPackageItem {
        out.endTag(null, TAG_SHORTCUT);
    }

    public static ShortcutPackage loadFromXml(XmlPullParser parser, int userId)
    public static ShortcutPackage loadFromXml(ShortcutService s, XmlPullParser parser,
            int ownerUserId, boolean fromBackup)
            throws IOException, XmlPullParserException {

        final String packageName = ShortcutService.parseStringAttribute(parser,
                ATTR_NAME);

        final ShortcutPackage ret = new ShortcutPackage(userId, packageName);
        final ShortcutPackage ret = new ShortcutPackage(ownerUserId, packageName);

        ret.mDynamicShortcutCount =
                ShortcutService.parseIntAttribute(parser, ATTR_DYNAMIC_COUNT);
@@ -478,6 +477,7 @@ class ShortcutPackage implements ShortcutPackageItem {
                ShortcutService.parseIntAttribute(parser, ATTR_CALL_COUNT);
        ret.mLastResetTime =
                ShortcutService.parseLongAttribute(parser, ATTR_LAST_RESET);
        ShortcutPackageInfo spi = null;

        final int outerDepth = parser.getDepth();
        int type;
@@ -488,7 +488,11 @@ class ShortcutPackage implements ShortcutPackageItem {
            }
            final int depth = parser.getDepth();
            final String tag = parser.getName();
            if (depth == outerDepth + 1) {
                switch (tag) {
                    case ShortcutPackageInfo.TAG_ROOT:
                        spi = ShortcutPackageInfo.loadFromXml(parser);
                        continue;
                    case TAG_SHORTCUT:
                        final ShortcutInfo si = parseShortcut(parser, packageName);

@@ -496,7 +500,11 @@ class ShortcutPackage implements ShortcutPackageItem {
                        ret.mShortcuts.put(si.getId(), si);
                        continue;
                }
            throw ShortcutService.throwForInvalidTag(depth, tag);
            }
            ShortcutService.warnForInvalidTag(depth, tag);
        }
        if (spi != null) {
            ret.replacePackageInfo(spi);
        }
        return ret;
    }
@@ -522,8 +530,7 @@ class ShortcutPackage implements ShortcutPackageItem {
        title = ShortcutService.parseStringAttribute(parser, ATTR_TITLE);
        intent = ShortcutService.parseIntentAttribute(parser, ATTR_INTENT);
        weight = (int) ShortcutService.parseLongAttribute(parser, ATTR_WEIGHT);
        lastChangedTimestamp = (int) ShortcutService.parseLongAttribute(parser,
                ATTR_TIMESTAMP);
        lastChangedTimestamp = ShortcutService.parseLongAttribute(parser, ATTR_TIMESTAMP);
        flags = (int) ShortcutService.parseLongAttribute(parser, ATTR_FLAGS);
        iconRes = (int) ShortcutService.parseLongAttribute(parser, ATTR_ICON_RES);
        bitmapPath = ShortcutService.parseStringAttribute(parser, ATTR_BITMAP_PATH);
+30 −140
Original line number Diff line number Diff line
@@ -15,14 +15,11 @@
 */
package com.android.server.pm;

import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.Signature;
import android.util.Slog;

import com.android.internal.util.Preconditions;
import com.android.server.backup.BackupUtils;

import libcore.io.Base64;
import libcore.util.HexEncoding;
@@ -33,32 +30,21 @@ import org.xmlpull.v1.XmlSerializer;

import java.io.IOException;
import java.io.PrintWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * Package information used by {@link android.content.pm.ShortcutManager} for backup / restore.
 *
 * TODO: The methods about signature hashes are copied from BackupManagerService, which is not
 * visible here.  Unify the code.
 */
class ShortcutPackageInfo implements ShortcutPackageItem {
class ShortcutPackageInfo {
    private static final String TAG = ShortcutService.TAG;

    static final String TAG_ROOT = "package-info";
    private static final String ATTR_USER_ID = "user";
    private static final String ATTR_NAME = "name";
    private static final String ATTR_VERSION = "version";
    private static final String ATTR_SHADOW = "shadow";

    private static final String TAG_SIGNATURE = "signature";
    private static final String ATTR_SIGNATURE_HASH = "hash";

    private final String mPackageName;
    private final int mUserId;

    /**
     * When true, this package information was restored from the previous device, and the app hasn't
     * been installed yet.
@@ -67,22 +53,14 @@ class ShortcutPackageInfo implements ShortcutPackageItem {
    private int mVersionCode;
    private ArrayList<byte[]> mSigHashes;

    private ShortcutPackageInfo(String packageName, int userId,
            int versionCode, ArrayList<byte[]> sigHashes, boolean isShadow) {
        mPackageName = Preconditions.checkNotNull(packageName);
        mUserId = userId;
    private ShortcutPackageInfo(int versionCode, ArrayList<byte[]> sigHashes, boolean isShadow) {
        mVersionCode = versionCode;
        mIsShadow = isShadow;
        mSigHashes = sigHashes;
    }

    @NonNull
    public String getPackageName() {
        return mPackageName;
    }

    public int getUserId() {
        return mUserId;
    public static ShortcutPackageInfo newEmpty() {
        return new ShortcutPackageInfo(0, new ArrayList<>(0), /* isShadow */ false);
    }

    public boolean isShadow() {
@@ -101,92 +79,13 @@ class ShortcutPackageInfo implements ShortcutPackageItem {
        return mVersionCode;
    }

    private static byte[] hashSignature(Signature sig) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            digest.update(sig.toByteArray());
            return digest.digest();
        } catch (NoSuchAlgorithmException e) {
            Slog.w(TAG, "No SHA-256 algorithm found!");
        }
        return null;
    }

    private static ArrayList<byte[]> hashSignatureArray(Signature[] sigs) {
        if (sigs == null) {
            return null;
        }

        ArrayList<byte[]> hashes = new ArrayList<byte[]>(sigs.length);
        for (Signature s : sigs) {
            hashes.add(hashSignature(s));
        }
        return hashes;
    }

    private static boolean signaturesMatch(ArrayList<byte[]> storedSigHashes, PackageInfo target) {
        if (target == null) {
            return false;
        }

        // If the target resides on the system partition, we allow it to restore
        // data from the like-named package in a restore set even if the signatures
        // do not match.  (Unlike general applications, those flashed to the system
        // partition will be signed with the device's platform certificate, so on
        // different phones the same system app will have different signatures.)
        if ((target.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
            return true;
        }

        // Allow unsigned apps, but not signed on one device and unsigned on the other
        // !!! TODO: is this the right policy?
        Signature[] deviceSigs = target.signatures;
        if ((storedSigHashes == null || storedSigHashes.size() == 0)
                && (deviceSigs == null || deviceSigs.length == 0)) {
            return true;
        }
        if (storedSigHashes == null || deviceSigs == null) {
            return false;
        }

        // !!! TODO: this demands that every stored signature match one
        // that is present on device, and does not demand the converse.
        // Is this this right policy?
        final int nStored = storedSigHashes.size();
        final int nDevice = deviceSigs.length;

        // hash each on-device signature
        ArrayList<byte[]> deviceHashes = new ArrayList<byte[]>(nDevice);
        for (int i = 0; i < nDevice; i++) {
            deviceHashes.add(hashSignature(deviceSigs[i]));
        }

        // now ensure that each stored sig (hash) matches an on-device sig (hash)
        for (int n = 0; n < nStored; n++) {
            boolean match = false;
            final byte[] storedHash = storedSigHashes.get(n);
            for (int i = 0; i < nDevice; i++) {
                if (Arrays.equals(storedHash, deviceHashes.get(i))) {
                    match = true;
                    break;
                }
            }
            // match is false when no on-device sig matched one of the stored ones
            if (!match) {
                return false;
            }
        }

        return true;
    }

    public boolean canRestoreTo(PackageInfo target) {
        if (target.versionCode < mVersionCode) {
            Slog.w(TAG, String.format("Package current version %d < backed up version %d",
                    target.versionCode, mVersionCode));
            return false;
        }
        if (!signaturesMatch(mSigHashes, target)) {
        if (!BackupUtils.signaturesMatch(mSigHashes, target)) {
            Slog.w(TAG, "Package signature mismtach");
            return false;
        }
@@ -194,37 +93,34 @@ class ShortcutPackageInfo implements ShortcutPackageItem {
    }

    public static ShortcutPackageInfo generateForInstalledPackage(
            ShortcutService s, String packageName, @UserIdInt int userId) {
        final PackageInfo pi = s.getPackageInfoWithSignatures(packageName, userId);
            ShortcutService s, String packageName, @UserIdInt int packageUserId) {
        final PackageInfo pi = s.getPackageInfoWithSignatures(packageName, packageUserId);
        if (pi.signatures == null || pi.signatures.length == 0) {
            Slog.e(TAG, "Can't get signatures: package=" + packageName);
            return null;
        }
        final ShortcutPackageInfo ret = new ShortcutPackageInfo(packageName, userId, pi.versionCode,
                hashSignatureArray(pi.signatures), /* shadow=*/ false);
        final ShortcutPackageInfo ret = new ShortcutPackageInfo(pi.versionCode,
                BackupUtils.hashSignatureArray(pi.signatures), /* shadow=*/ false);

        return ret;
    }

    public void refreshAndSave(ShortcutService s, @UserIdInt int userId) {
        final PackageInfo pi = s.getPackageInfoWithSignatures(mPackageName, userId);
    public void refresh(ShortcutService s, ShortcutPackageItem pkg) {
        // Note use mUserId here, rather than userId.
        final PackageInfo pi = s.getPackageInfoWithSignatures(
                pkg.getPackageName(), pkg.getPackageUserId());
        if (pi == null) {
            Slog.w(TAG, "Package not found: " + mPackageName);
            Slog.w(TAG, "Package not found: " + pkg.getPackageName());
            return;
        }
        mVersionCode = pi.versionCode;
        mSigHashes = hashSignatureArray(pi.signatures);

        s.scheduleSaveUser(userId);
        mSigHashes = BackupUtils.hashSignatureArray(pi.signatures);
    }

    public void saveToXml(XmlSerializer out, boolean forBackup)
            throws IOException, XmlPullParserException {
    public void saveToXml(XmlSerializer out) throws IOException {

        out.startTag(null, TAG_ROOT);

        ShortcutService.writeAttr(out, ATTR_NAME, mPackageName);
        ShortcutService.writeAttr(out, ATTR_USER_ID, mUserId);
        ShortcutService.writeAttr(out, ATTR_VERSION, mVersionCode);
        ShortcutService.writeAttr(out, ATTR_SHADOW, mIsShadow);

@@ -236,11 +132,9 @@ class ShortcutPackageInfo implements ShortcutPackageItem {
        out.endTag(null, TAG_ROOT);
    }

    public static ShortcutPackageInfo loadFromXml(XmlPullParser parser, int ownerUserId)
    public static ShortcutPackageInfo loadFromXml(XmlPullParser parser)
            throws IOException, XmlPullParserException {

        final String packageName = ShortcutService.parseStringAttribute(parser, ATTR_NAME);
        final int userId = ShortcutService.parseIntAttribute(parser, ATTR_USER_ID, ownerUserId);
        final int versionCode = ShortcutService.parseIntAttribute(parser, ATTR_VERSION);
        final boolean shadow = ShortcutService.parseBooleanAttribute(parser, ATTR_SHADOW);

@@ -256,6 +150,8 @@ class ShortcutPackageInfo implements ShortcutPackageItem {
            }
            final int depth = parser.getDepth();
            final String tag = parser.getName();

            if (depth == outerDepth + 1) {
                switch (tag) {
                    case TAG_SIGNATURE: {
                        final String hash = ShortcutService.parseStringAttribute(
@@ -264,23 +160,17 @@ class ShortcutPackageInfo implements ShortcutPackageItem {
                        continue;
                    }
                }
            throw ShortcutService.throwForInvalidTag(depth, tag);
            }
        return new ShortcutPackageInfo(packageName, userId, versionCode, hashes, shadow);
            ShortcutService.warnForInvalidTag(depth, tag);
        }
        return new ShortcutPackageInfo(versionCode, hashes, shadow);
    }

    public void dump(ShortcutService s, PrintWriter pw, String prefix) {
        pw.println();

        pw.print(prefix);
        pw.print("PackageInfo: ");
        pw.print(mPackageName);
        pw.println();

        pw.print(prefix);
        pw.print("  User: ");
        pw.print(mUserId);
        pw.println();
        pw.println("PackageInfo:");

        pw.print(prefix);
        pw.print("  IsShadow: ");
+57 −3

File changed.

Preview size limit exceeded, changes collapsed.

Loading