Loading core/api/current.txt +1 −1 Original line number Diff line number Diff line Loading @@ -12053,7 +12053,6 @@ package android.content.pm { public static class PackageInstaller.Session implements java.io.Closeable { method public void abandon(); method @Deprecated public void addChecksums(@NonNull String, @NonNull java.util.List<android.content.pm.Checksum>) throws java.io.IOException; method public void addChildSessionId(int); method public void close(); method public void commit(@NonNull android.content.IntentSender); Loading @@ -12067,6 +12066,7 @@ package android.content.pm { method @NonNull public java.io.OutputStream openWrite(@NonNull String, long, long) throws java.io.IOException; method public void removeChildSessionId(int); method public void removeSplit(@NonNull String) throws java.io.IOException; method @Deprecated public void setChecksums(@NonNull String, @NonNull java.util.List<android.content.pm.Checksum>, @Nullable byte[]) throws java.io.IOException; method public void setStagingProgress(float); method public void transfer(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; } core/java/android/content/pm/IPackageInstallerSession.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ interface IPackageInstallerSession { void write(String name, long offsetBytes, long lengthBytes, in ParcelFileDescriptor fd); void stageViaHardLink(String target); void addChecksums(String name, in Checksum[] checksums); void setChecksums(String name, in Checksum[] checksums, in byte[] signature); void removeSplit(String splitName); Loading core/java/android/content/pm/PackageInstaller.java +8 −4 Original line number Diff line number Diff line Loading @@ -1247,12 +1247,15 @@ public class PackageInstaller { } /** * Adds installer-provided checksums for the APK file in session. * Sets installer-provided checksums for the APK file in session. * * @param name previously written as part of this session. * {@link #openWrite} * @param checksums installer intends to make available via * {@link PackageManager#requestChecksums}. * @param signature PKCS#7 detached signature bytes over serialized checksums to enable * fs-verity for the checksums or null if fs-verity should not be enabled. * @see <a href="https://www.kernel.org/doc/html/latest/filesystems/fsverity.html#built-in-signature-verification">fs-verity</a> * @throws SecurityException if called after the session has been * committed or abandoned. * @throws IllegalStateException if checksums for this file have already been added. Loading @@ -1262,13 +1265,14 @@ public class PackageInstaller { * in {@link PackageManager#requestChecksums}. */ @Deprecated public void addChecksums(@NonNull String name, @NonNull List<Checksum> checksums) throws IOException { public void setChecksums(@NonNull String name, @NonNull List<Checksum> checksums, @Nullable byte[] signature) throws IOException { Objects.requireNonNull(name); Objects.requireNonNull(checksums); try { mSession.addChecksums(name, checksums.toArray(new Checksum[checksums.size()])); mSession.setChecksums(name, checksums.toArray(new Checksum[checksums.size()]), signature); } catch (RuntimeException e) { ExceptionUtils.maybeUnwrapIOException(e); throw e; Loading services/core/java/com/android/server/pm/PackageInstallerSession.java +102 −25 Original line number Diff line number Diff line Loading @@ -187,6 +187,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { static final String TAG_CHILD_SESSION = "childSession"; static final String TAG_SESSION_FILE = "sessionFile"; static final String TAG_SESSION_CHECKSUM = "sessionChecksum"; static final String TAG_SESSION_CHECKSUM_SIGNATURE = "sessionChecksumSignature"; private static final String TAG_GRANTED_RUNTIME_PERMISSION = "granted-runtime-permission"; private static final String TAG_WHITELISTED_RESTRICTED_PERMISSION = "whitelisted-restricted-permission"; Loading Loading @@ -400,8 +401,26 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @GuardedBy("mLock") private ArraySet<FileEntry> mFiles = new ArraySet<>(); static class PerFileChecksum { private final Checksum[] mChecksums; private final byte[] mSignature; PerFileChecksum(Checksum[] checksums, byte[] signature) { mChecksums = checksums; mSignature = signature; } Checksum[] getChecksums() { return this.mChecksums; } byte[] getSignature() { return this.mSignature; } } @GuardedBy("mLock") private ArrayMap<String, Checksum[]> mChecksums = new ArrayMap<>(); private ArrayMap<String, PerFileChecksum> mChecksums = new ArrayMap<>(); @Nullable final StagedSession mStagedSession; Loading Loading @@ -924,7 +943,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { int sessionId, int userId, int installerUid, @NonNull InstallSource installSource, SessionParams params, long createdMillis, long committedMillis, File stageDir, String stageCid, InstallationFile[] files, ArrayMap<String, List<Checksum>> checksums, ArrayMap<String, PerFileChecksum> checksums, boolean prepared, boolean committed, boolean destroyed, boolean sealed, @Nullable int[] childSessionIds, int parentSessionId, boolean isReady, boolean isFailed, boolean isApplied, int stagedSessionErrorCode, Loading Loading @@ -970,11 +989,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } if (checksums != null) { for (int i = 0, isize = checksums.size(); i < isize; ++i) { final String fileName = checksums.keyAt(i); final List<Checksum> fileChecksums = checksums.valueAt(i); mChecksums.put(fileName, fileChecksums.toArray(new Checksum[fileChecksums.size()])); } mChecksums.putAll(checksums); } if (!params.isMultiPackage && (stageDir == null) == (stageCid == null)) { Loading Loading @@ -1261,7 +1276,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } @Override public void addChecksums(String name, @NonNull Checksum[] checksums) { public void setChecksums(String name, @NonNull Checksum[] checksums, @Nullable byte[] signature) { if (checksums.length == 0) { return; } Loading @@ -1277,6 +1293,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { throw new IllegalStateException("Can't obtain calling installer's package."); } if (signature != null && signature.length != 0) { final boolean standardMode = PackageManagerServiceUtils.isApkVerityEnabled(); final boolean legacyMode = PackageManagerServiceUtils.isLegacyApkVerityEnabled(); if (!standardMode || legacyMode) { Slog.e(TAG, "Can't enforce checksum's signature: Apk-Verity is disabled or in legacy " + "mode."); signature = null; } } synchronized (mLock) { assertCallerIsOwnerOrRootLocked(); assertPreparedAndNotCommittedOrDestroyedLocked("addChecksums"); Loading @@ -1285,7 +1312,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { throw new IllegalStateException("Duplicate checksums."); } mChecksums.put(name, checksums); mChecksums.put(name, new PerFileChecksum(checksums, signature)); } } Loading Loading @@ -3040,15 +3067,25 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { maybeStageFsveritySignatureLocked(dexMetadataFile, targetDexMetadataFile); } private void storeBytesToInstallationFile(final String localPath, final String absolutePath, final byte[] bytes) throws IOException { if (!isIncrementalInstallation() || mIncrementalFileStorages == null) { FileUtils.bytesToFile(absolutePath, bytes); } else { mIncrementalFileStorages.makeFile(localPath, bytes); } } @GuardedBy("mLock") private void maybeStageDigestsLocked(File origFile, File targetFile, String splitName) throws PackageManagerException { final Checksum[] checksums = mChecksums.get(origFile.getName()); if (checksums == null) { final PerFileChecksum perFileChecksum = mChecksums.get(origFile.getName()); if (perFileChecksum == null) { return; } mChecksums.remove(origFile.getName()); final Checksum[] checksums = perFileChecksum.getChecksums(); if (checksums.length == 0) { return; } Loading @@ -3056,14 +3093,24 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final String targetDigestsPath = ApkChecksums.buildDigestsPathForApk(targetFile.getName()); final File targetDigestsFile = new File(stageDir, targetDigestsPath); try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { // Storing and staging checksums. ApkChecksums.writeChecksums(os, checksums); final byte[] checksumsBytes = os.toByteArray(); storeBytesToInstallationFile(targetDigestsPath, targetDigestsFile.getAbsolutePath(), os.toByteArray()); stageFileLocked(targetDigestsFile, targetDigestsFile); if (!isIncrementalInstallation() || mIncrementalFileStorages == null) { FileUtils.bytesToFile(targetDigestsFile.getAbsolutePath(), checksumsBytes); } else { mIncrementalFileStorages.makeFile(targetDigestsPath, checksumsBytes); final byte[] signature = perFileChecksum.getSignature(); if (signature == null || signature.length == 0) { return; } // Storing and staging signature. final String targetDigestsSignaturePath = VerityUtils.getFsveritySignatureFilePath( targetDigestsPath); final File targetDigestsSignatureFile = new File(stageDir, targetDigestsSignaturePath); storeBytesToInstallationFile(targetDigestsSignaturePath, targetDigestsSignatureFile.getAbsolutePath(), signature); stageFileLocked(targetDigestsSignatureFile, targetDigestsSignatureFile); } catch (CertificateException e) { throw new PackageManagerException(INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING, "Failed to encode certificate for " + mPackageName, e); Loading @@ -3071,8 +3118,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed to store digests for " + mPackageName, e); } stageFileLocked(targetDigestsFile, targetDigestsFile); } @GuardedBy("mLock") Loading Loading @@ -4294,7 +4339,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { for (int i = 0, isize = mChecksums.size(); i < isize; ++i) { final String fileName = mChecksums.keyAt(i); final Checksum[] checksums = mChecksums.valueAt(i); final PerFileChecksum perFileChecksum = mChecksums.valueAt(i); final Checksum[] checksums = perFileChecksum.getChecksums(); for (Checksum checksum : checksums) { out.startTag(null, TAG_SESSION_CHECKSUM); writeStringAttribute(out, ATTR_NAME, fileName); Loading @@ -4303,6 +4349,19 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { out.endTag(null, TAG_SESSION_CHECKSUM); } } for (int i = 0, isize = mChecksums.size(); i < isize; ++i) { final String fileName = mChecksums.keyAt(i); final PerFileChecksum perFileChecksum = mChecksums.valueAt(i); final byte[] signature = perFileChecksum.getSignature(); if (signature == null || signature.length == 0) { continue; } out.startTag(null, TAG_SESSION_CHECKSUM_SIGNATURE); writeStringAttribute(out, ATTR_NAME, fileName); writeByteArrayAttribute(out, ATTR_SIGNATURE, signature); out.endTag(null, TAG_SESSION_CHECKSUM_SIGNATURE); } } out.endTag(null, TAG_SESSION); Loading Loading @@ -4418,6 +4477,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { List<Integer> childSessionIds = new ArrayList<>(); List<InstallationFile> files = new ArrayList<>(); ArrayMap<String, List<Checksum>> checksums = new ArrayMap<>(); ArrayMap<String, byte[]> signatures = new ArrayMap<>(); int outerDepth = in.getDepth(); int type; while ((type = in.next()) != XmlPullParser.END_DOCUMENT Loading Loading @@ -4460,6 +4520,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } fileChecksums.add(checksum); } if (TAG_SESSION_CHECKSUM_SIGNATURE.equals(in.getName())) { final String fileName = readStringAttribute(in, ATTR_NAME); final byte[] signature = readByteArrayAttribute(in, ATTR_SIGNATURE); signatures.put(fileName, signature); } } if (grantedRuntimePermissions.size() > 0) { Loading Loading @@ -4488,13 +4553,25 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { fileArray = files.toArray(EMPTY_INSTALLATION_FILE_ARRAY); } ArrayMap<String, PerFileChecksum> checksumsMap = null; if (!checksums.isEmpty()) { checksumsMap = new ArrayMap<>(checksums.size()); for (int i = 0, isize = checksums.size(); i < isize; ++i) { final String fileName = checksums.keyAt(i); final List<Checksum> perFileChecksum = checksums.valueAt(i); final byte[] perFileSignature = signatures.get(fileName); checksumsMap.put(fileName, new PerFileChecksum( perFileChecksum.toArray(new Checksum[perFileChecksum.size()]), perFileSignature)); } } InstallSource installSource = InstallSource.create(installInitiatingPackageName, installOriginatingPackageName, installerPackageName, installerAttributionTag); return new PackageInstallerSession(callback, context, pm, sessionProvider, installerThread, stagingManager, sessionId, userId, installerUid, installSource, params, createdMillis, committedMillis, stageDir, stageCid, fileArray, checksums, prepared, committed, destroyed, sealed, childSessionIdsArray, parentSessionId, isReady, isFailed, isApplied, stagedSessionErrorCode, stagedSessionErrorMessage); return new PackageInstallerSession(callback, context, pm, sessionProvider, installerThread, stagingManager, sessionId, userId, installerUid, installSource, params, createdMillis, committedMillis, stageDir, stageCid, fileArray, checksumsMap, prepared, committed, destroyed, sealed, childSessionIdsArray, parentSessionId, isReady, isFailed, isApplied, stagedSessionErrorCode, stagedSessionErrorMessage); } } Loading
core/api/current.txt +1 −1 Original line number Diff line number Diff line Loading @@ -12053,7 +12053,6 @@ package android.content.pm { public static class PackageInstaller.Session implements java.io.Closeable { method public void abandon(); method @Deprecated public void addChecksums(@NonNull String, @NonNull java.util.List<android.content.pm.Checksum>) throws java.io.IOException; method public void addChildSessionId(int); method public void close(); method public void commit(@NonNull android.content.IntentSender); Loading @@ -12067,6 +12066,7 @@ package android.content.pm { method @NonNull public java.io.OutputStream openWrite(@NonNull String, long, long) throws java.io.IOException; method public void removeChildSessionId(int); method public void removeSplit(@NonNull String) throws java.io.IOException; method @Deprecated public void setChecksums(@NonNull String, @NonNull java.util.List<android.content.pm.Checksum>, @Nullable byte[]) throws java.io.IOException; method public void setStagingProgress(float); method public void transfer(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; }
core/java/android/content/pm/IPackageInstallerSession.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ interface IPackageInstallerSession { void write(String name, long offsetBytes, long lengthBytes, in ParcelFileDescriptor fd); void stageViaHardLink(String target); void addChecksums(String name, in Checksum[] checksums); void setChecksums(String name, in Checksum[] checksums, in byte[] signature); void removeSplit(String splitName); Loading
core/java/android/content/pm/PackageInstaller.java +8 −4 Original line number Diff line number Diff line Loading @@ -1247,12 +1247,15 @@ public class PackageInstaller { } /** * Adds installer-provided checksums for the APK file in session. * Sets installer-provided checksums for the APK file in session. * * @param name previously written as part of this session. * {@link #openWrite} * @param checksums installer intends to make available via * {@link PackageManager#requestChecksums}. * @param signature PKCS#7 detached signature bytes over serialized checksums to enable * fs-verity for the checksums or null if fs-verity should not be enabled. * @see <a href="https://www.kernel.org/doc/html/latest/filesystems/fsverity.html#built-in-signature-verification">fs-verity</a> * @throws SecurityException if called after the session has been * committed or abandoned. * @throws IllegalStateException if checksums for this file have already been added. Loading @@ -1262,13 +1265,14 @@ public class PackageInstaller { * in {@link PackageManager#requestChecksums}. */ @Deprecated public void addChecksums(@NonNull String name, @NonNull List<Checksum> checksums) throws IOException { public void setChecksums(@NonNull String name, @NonNull List<Checksum> checksums, @Nullable byte[] signature) throws IOException { Objects.requireNonNull(name); Objects.requireNonNull(checksums); try { mSession.addChecksums(name, checksums.toArray(new Checksum[checksums.size()])); mSession.setChecksums(name, checksums.toArray(new Checksum[checksums.size()]), signature); } catch (RuntimeException e) { ExceptionUtils.maybeUnwrapIOException(e); throw e; Loading
services/core/java/com/android/server/pm/PackageInstallerSession.java +102 −25 Original line number Diff line number Diff line Loading @@ -187,6 +187,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { static final String TAG_CHILD_SESSION = "childSession"; static final String TAG_SESSION_FILE = "sessionFile"; static final String TAG_SESSION_CHECKSUM = "sessionChecksum"; static final String TAG_SESSION_CHECKSUM_SIGNATURE = "sessionChecksumSignature"; private static final String TAG_GRANTED_RUNTIME_PERMISSION = "granted-runtime-permission"; private static final String TAG_WHITELISTED_RESTRICTED_PERMISSION = "whitelisted-restricted-permission"; Loading Loading @@ -400,8 +401,26 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @GuardedBy("mLock") private ArraySet<FileEntry> mFiles = new ArraySet<>(); static class PerFileChecksum { private final Checksum[] mChecksums; private final byte[] mSignature; PerFileChecksum(Checksum[] checksums, byte[] signature) { mChecksums = checksums; mSignature = signature; } Checksum[] getChecksums() { return this.mChecksums; } byte[] getSignature() { return this.mSignature; } } @GuardedBy("mLock") private ArrayMap<String, Checksum[]> mChecksums = new ArrayMap<>(); private ArrayMap<String, PerFileChecksum> mChecksums = new ArrayMap<>(); @Nullable final StagedSession mStagedSession; Loading Loading @@ -924,7 +943,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { int sessionId, int userId, int installerUid, @NonNull InstallSource installSource, SessionParams params, long createdMillis, long committedMillis, File stageDir, String stageCid, InstallationFile[] files, ArrayMap<String, List<Checksum>> checksums, ArrayMap<String, PerFileChecksum> checksums, boolean prepared, boolean committed, boolean destroyed, boolean sealed, @Nullable int[] childSessionIds, int parentSessionId, boolean isReady, boolean isFailed, boolean isApplied, int stagedSessionErrorCode, Loading Loading @@ -970,11 +989,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } if (checksums != null) { for (int i = 0, isize = checksums.size(); i < isize; ++i) { final String fileName = checksums.keyAt(i); final List<Checksum> fileChecksums = checksums.valueAt(i); mChecksums.put(fileName, fileChecksums.toArray(new Checksum[fileChecksums.size()])); } mChecksums.putAll(checksums); } if (!params.isMultiPackage && (stageDir == null) == (stageCid == null)) { Loading Loading @@ -1261,7 +1276,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } @Override public void addChecksums(String name, @NonNull Checksum[] checksums) { public void setChecksums(String name, @NonNull Checksum[] checksums, @Nullable byte[] signature) { if (checksums.length == 0) { return; } Loading @@ -1277,6 +1293,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { throw new IllegalStateException("Can't obtain calling installer's package."); } if (signature != null && signature.length != 0) { final boolean standardMode = PackageManagerServiceUtils.isApkVerityEnabled(); final boolean legacyMode = PackageManagerServiceUtils.isLegacyApkVerityEnabled(); if (!standardMode || legacyMode) { Slog.e(TAG, "Can't enforce checksum's signature: Apk-Verity is disabled or in legacy " + "mode."); signature = null; } } synchronized (mLock) { assertCallerIsOwnerOrRootLocked(); assertPreparedAndNotCommittedOrDestroyedLocked("addChecksums"); Loading @@ -1285,7 +1312,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { throw new IllegalStateException("Duplicate checksums."); } mChecksums.put(name, checksums); mChecksums.put(name, new PerFileChecksum(checksums, signature)); } } Loading Loading @@ -3040,15 +3067,25 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { maybeStageFsveritySignatureLocked(dexMetadataFile, targetDexMetadataFile); } private void storeBytesToInstallationFile(final String localPath, final String absolutePath, final byte[] bytes) throws IOException { if (!isIncrementalInstallation() || mIncrementalFileStorages == null) { FileUtils.bytesToFile(absolutePath, bytes); } else { mIncrementalFileStorages.makeFile(localPath, bytes); } } @GuardedBy("mLock") private void maybeStageDigestsLocked(File origFile, File targetFile, String splitName) throws PackageManagerException { final Checksum[] checksums = mChecksums.get(origFile.getName()); if (checksums == null) { final PerFileChecksum perFileChecksum = mChecksums.get(origFile.getName()); if (perFileChecksum == null) { return; } mChecksums.remove(origFile.getName()); final Checksum[] checksums = perFileChecksum.getChecksums(); if (checksums.length == 0) { return; } Loading @@ -3056,14 +3093,24 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final String targetDigestsPath = ApkChecksums.buildDigestsPathForApk(targetFile.getName()); final File targetDigestsFile = new File(stageDir, targetDigestsPath); try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { // Storing and staging checksums. ApkChecksums.writeChecksums(os, checksums); final byte[] checksumsBytes = os.toByteArray(); storeBytesToInstallationFile(targetDigestsPath, targetDigestsFile.getAbsolutePath(), os.toByteArray()); stageFileLocked(targetDigestsFile, targetDigestsFile); if (!isIncrementalInstallation() || mIncrementalFileStorages == null) { FileUtils.bytesToFile(targetDigestsFile.getAbsolutePath(), checksumsBytes); } else { mIncrementalFileStorages.makeFile(targetDigestsPath, checksumsBytes); final byte[] signature = perFileChecksum.getSignature(); if (signature == null || signature.length == 0) { return; } // Storing and staging signature. final String targetDigestsSignaturePath = VerityUtils.getFsveritySignatureFilePath( targetDigestsPath); final File targetDigestsSignatureFile = new File(stageDir, targetDigestsSignaturePath); storeBytesToInstallationFile(targetDigestsSignaturePath, targetDigestsSignatureFile.getAbsolutePath(), signature); stageFileLocked(targetDigestsSignatureFile, targetDigestsSignatureFile); } catch (CertificateException e) { throw new PackageManagerException(INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING, "Failed to encode certificate for " + mPackageName, e); Loading @@ -3071,8 +3118,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed to store digests for " + mPackageName, e); } stageFileLocked(targetDigestsFile, targetDigestsFile); } @GuardedBy("mLock") Loading Loading @@ -4294,7 +4339,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { for (int i = 0, isize = mChecksums.size(); i < isize; ++i) { final String fileName = mChecksums.keyAt(i); final Checksum[] checksums = mChecksums.valueAt(i); final PerFileChecksum perFileChecksum = mChecksums.valueAt(i); final Checksum[] checksums = perFileChecksum.getChecksums(); for (Checksum checksum : checksums) { out.startTag(null, TAG_SESSION_CHECKSUM); writeStringAttribute(out, ATTR_NAME, fileName); Loading @@ -4303,6 +4349,19 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { out.endTag(null, TAG_SESSION_CHECKSUM); } } for (int i = 0, isize = mChecksums.size(); i < isize; ++i) { final String fileName = mChecksums.keyAt(i); final PerFileChecksum perFileChecksum = mChecksums.valueAt(i); final byte[] signature = perFileChecksum.getSignature(); if (signature == null || signature.length == 0) { continue; } out.startTag(null, TAG_SESSION_CHECKSUM_SIGNATURE); writeStringAttribute(out, ATTR_NAME, fileName); writeByteArrayAttribute(out, ATTR_SIGNATURE, signature); out.endTag(null, TAG_SESSION_CHECKSUM_SIGNATURE); } } out.endTag(null, TAG_SESSION); Loading Loading @@ -4418,6 +4477,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { List<Integer> childSessionIds = new ArrayList<>(); List<InstallationFile> files = new ArrayList<>(); ArrayMap<String, List<Checksum>> checksums = new ArrayMap<>(); ArrayMap<String, byte[]> signatures = new ArrayMap<>(); int outerDepth = in.getDepth(); int type; while ((type = in.next()) != XmlPullParser.END_DOCUMENT Loading Loading @@ -4460,6 +4520,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } fileChecksums.add(checksum); } if (TAG_SESSION_CHECKSUM_SIGNATURE.equals(in.getName())) { final String fileName = readStringAttribute(in, ATTR_NAME); final byte[] signature = readByteArrayAttribute(in, ATTR_SIGNATURE); signatures.put(fileName, signature); } } if (grantedRuntimePermissions.size() > 0) { Loading Loading @@ -4488,13 +4553,25 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { fileArray = files.toArray(EMPTY_INSTALLATION_FILE_ARRAY); } ArrayMap<String, PerFileChecksum> checksumsMap = null; if (!checksums.isEmpty()) { checksumsMap = new ArrayMap<>(checksums.size()); for (int i = 0, isize = checksums.size(); i < isize; ++i) { final String fileName = checksums.keyAt(i); final List<Checksum> perFileChecksum = checksums.valueAt(i); final byte[] perFileSignature = signatures.get(fileName); checksumsMap.put(fileName, new PerFileChecksum( perFileChecksum.toArray(new Checksum[perFileChecksum.size()]), perFileSignature)); } } InstallSource installSource = InstallSource.create(installInitiatingPackageName, installOriginatingPackageName, installerPackageName, installerAttributionTag); return new PackageInstallerSession(callback, context, pm, sessionProvider, installerThread, stagingManager, sessionId, userId, installerUid, installSource, params, createdMillis, committedMillis, stageDir, stageCid, fileArray, checksums, prepared, committed, destroyed, sealed, childSessionIdsArray, parentSessionId, isReady, isFailed, isApplied, stagedSessionErrorCode, stagedSessionErrorMessage); return new PackageInstallerSession(callback, context, pm, sessionProvider, installerThread, stagingManager, sessionId, userId, installerUid, installSource, params, createdMillis, committedMillis, stageDir, stageCid, fileArray, checksumsMap, prepared, committed, destroyed, sealed, childSessionIdsArray, parentSessionId, isReady, isFailed, isApplied, stagedSessionErrorCode, stagedSessionErrorMessage); } }