Loading core/java/android/content/pm/PackageInstaller.java +14 −0 Original line number Diff line number Diff line Loading @@ -2934,6 +2934,8 @@ public class PackageInstaller { public int unarchiveId = -1; /** {@hide} */ public @Nullable String dexoptCompilerFilter = null; /** {@hide} */ public boolean forceVerification; private final ArrayMap<String, Integer> mPermissionStates; Loading Loading @@ -2988,6 +2990,7 @@ public class PackageInstaller { developmentInstallFlags = source.readInt(); unarchiveId = source.readInt(); dexoptCompilerFilter = source.readString(); forceVerification = source.readBoolean(); } /** {@hide} */ Loading Loading @@ -3024,6 +3027,7 @@ public class PackageInstaller { ret.developmentInstallFlags = developmentInstallFlags; ret.unarchiveId = unarchiveId; ret.dexoptCompilerFilter = dexoptCompilerFilter; ret.forceVerification = forceVerification; return ret; } Loading Loading @@ -3732,6 +3736,14 @@ public class PackageInstaller { return grantedPermissions.toArray(ArrayUtils.emptyArray(String.class)); } /** * Used by adb installations to force enable the verification for this install. * {@hide} */ public void setForceVerification() { this.forceVerification = true; } /** {@hide} */ public void dump(IndentingPrintWriter pw) { pw.printPair("mode", mode); Loading Loading @@ -3767,6 +3779,7 @@ public class PackageInstaller { pw.printHexPair("developmentInstallFlags", developmentInstallFlags); pw.printPair("unarchiveId", unarchiveId); pw.printPair("dexoptCompilerFilter", dexoptCompilerFilter); pw.printPair("forceVerification", forceVerification); pw.println(); } Loading Loading @@ -3813,6 +3826,7 @@ public class PackageInstaller { dest.writeInt(developmentInstallFlags); dest.writeInt(unarchiveId); dest.writeString(dexoptCompilerFilter); dest.writeBoolean(forceVerification); } public static final Parcelable.Creator<SessionParams> Loading services/core/java/com/android/server/pm/PackageInstallerSession.java +49 −29 Original line number Diff line number Diff line Loading @@ -234,7 +234,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Predicate; import java.util.function.Supplier; public class PackageInstallerSession extends IPackageInstallerSession.Stub { private static final String TAG = "PackageInstallerSession"; Loading Loading @@ -1279,9 +1278,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } if (Flags.verificationService()) { if (shouldUseVerificationService()) { // Start binding to the verification service, if not bound already. mVerifierController.bindToVerifierServiceIfNeeded(() -> pm.snapshotComputer(), userId); mVerifierController.bindToVerifierServiceIfNeeded(mPm::snapshotComputer, userId); if (!TextUtils.isEmpty(params.appPackageName)) { mVerifierController.notifyPackageNameAvailable(params.appPackageName); } Loading Loading @@ -2875,9 +2874,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { setSessionFailed(e.error, errorMsg); onSessionVerificationFailure(e.error, errorMsg, /* extras= */ null); } if (Flags.verificationService()) { final Supplier<Computer> snapshotSupplier = mPm::snapshotComputer; if (mVerifierController.isVerifierInstalled(snapshotSupplier, userId)) { if (shouldUseVerificationService()) { final SigningInfo signingInfo; final List<SharedLibraryInfo> declaredLibraries; synchronized (mLock) { Loading @@ -2887,7 +2884,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } // Send the request to the verifier and wait for its response before the rest of // the installation can proceed. if (!mVerifierController.startVerificationSession(snapshotSupplier, userId, if (!mVerifierController.startVerificationSession(mPm::snapshotComputer, userId, sessionId, getPackageName(), Uri.fromFile(stageDir), signingInfo, declaredLibraries, mVerificationPolicy.get(), /* extensionParams= */ null, new VerifierCallback(), /* retry= */ false)) { Loading @@ -2897,13 +2894,36 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { /* extras= */ null); } } else { // Verifier is not installed. Let the installation pass for now. // No need to check with verifier. Proceed with the rest of the verification. resumeVerify(); } } else { // New verification feature is not enabled. Proceed to the rest of the verification. resumeVerify(); } private boolean shouldUseVerificationService() { if (!Flags.verificationService()) { // Feature is not enabled. return false; } if ((params.installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { // adb installs are exempted from verification unless explicitly requested if (!params.forceVerification) { return false; } } final String verifierPackageName = mVerifierController.getVerifierPackageName( mPm::snapshotComputer, userId); if (verifierPackageName == null) { // Feature is enabled but no verifier installed. return false; } synchronized (mLock) { if (verifierPackageName.equals(mPackageName)) { // The verifier itself is being updated. Skip. Slog.w(TAG, "Skipping verification service because the verifier is being updated"); return false; } } return true; } private void resumeVerify() { Loading Loading @@ -5597,7 +5617,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } catch (InstallerException ignored) { } if (Flags.verificationService() if (shouldUseVerificationService() && !TextUtils.isEmpty(params.appPackageName) && !isCommitted()) { // Only notify for the cancellation if the verification request has not Loading services/core/java/com/android/server/pm/PackageManagerShellCommand.java +4 −0 Original line number Diff line number Diff line Loading @@ -3599,6 +3599,9 @@ class PackageManagerShellCommand extends ShellCommand { .setCompilerFilter(sessionParams.dexoptCompilerFilter) .build(); break; case "--force-verification": sessionParams.setForceVerification(); break; default: throw new IllegalArgumentException("Unknown option " + opt); } Loading Loading @@ -4805,6 +4808,7 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" https://source.android.com/docs/core/runtime/configure" + "#compiler_filters"); pw.println(" or 'skip'"); pw.println(" --force-verification: if set, enable the verification for this install"); pw.println(""); pw.println(" install-existing [--user USER_ID|all|current]"); pw.println(" [--instant] [--full] [--wait] [--restrict-permissions] PACKAGE"); Loading services/core/java/com/android/server/pm/verify/pkg/VerificationStatusTracker.java +1 −11 Original line number Diff line number Diff line Loading @@ -30,9 +30,6 @@ public final class VerificationStatusTracker { private final @CurrentTimeMillisLong long mMaxTimeoutTime; @NonNull private final VerifierController.Injector mInjector; // Record the package name associated with the verification result @NonNull private final String mPackageName; /** * By default, the timeout time is the default timeout duration plus the current time (when Loading @@ -41,10 +38,8 @@ public final class VerificationStatusTracker { * can be extended via {@link #extendTimeRemaining} to the maximum allowed. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED) public VerificationStatusTracker(@NonNull String packageName, long defaultTimeoutMillis, long maxExtendedTimeoutMillis, public VerificationStatusTracker(long defaultTimeoutMillis, long maxExtendedTimeoutMillis, @NonNull VerifierController.Injector injector) { mPackageName = packageName; mStartTime = injector.getCurrentTimeMillis(); mTimeoutTime = mStartTime + defaultTimeoutMillis; mMaxTimeoutTime = mStartTime + maxExtendedTimeoutMillis; Loading Loading @@ -93,9 +88,4 @@ public final class VerificationStatusTracker { public boolean isTimeout() { return mInjector.getCurrentTimeMillis() >= mTimeoutTime; } @NonNull public String getPackageName() { return mPackageName; } } services/core/java/com/android/server/pm/verify/pkg/VerifierController.java +14 −8 Original line number Diff line number Diff line Loading @@ -139,15 +139,16 @@ public class VerifierController { } /** * Used by the installation session to check if a verifier is installed. * Used by the installation session to get the package name of the installed verifier. */ public boolean isVerifierInstalled(Supplier<Computer> snapshotSupplier, int userId) { @Nullable public String getVerifierPackageName(Supplier<Computer> snapshotSupplier, int userId) { if (isVerifierConnected()) { // Verifier is connected or is being connected, so it must be installed. return true; return mRemoteServiceComponentName.getPackageName(); } // Verifier has been disconnected, or it hasn't been connected. Check if it's installed. return mInjector.isVerifierInstalled(snapshotSupplier.get(), userId); return mInjector.getVerifierPackageName(snapshotSupplier.get(), userId); } /** Loading Loading @@ -331,7 +332,7 @@ public class VerifierController { final long defaultTimeoutMillis = mInjector.getVerificationRequestTimeoutMillis(); final long maxExtendedTimeoutMillis = mInjector.getMaxVerificationExtendedTimeoutMillis(); final VerificationStatusTracker tracker = new VerificationStatusTracker( packageName, defaultTimeoutMillis, maxExtendedTimeoutMillis, mInjector); defaultTimeoutMillis, maxExtendedTimeoutMillis, mInjector); synchronized (mVerificationStatus) { mVerificationStatus.put(verificationId, tracker); } Loading Loading @@ -542,10 +543,15 @@ public class VerifierController { } /** * Check if a verifier is installed on this device. * Return the package name of the verifier installed on this device. */ public boolean isVerifierInstalled(Computer snapshot, int userId) { return resolveVerifierComponentName(snapshot, userId) != null; @Nullable public String getVerifierPackageName(Computer snapshot, int userId) { final ComponentName componentName = resolveVerifierComponentName(snapshot, userId); if (componentName == null) { return null; } return componentName.getPackageName(); } /** Loading Loading
core/java/android/content/pm/PackageInstaller.java +14 −0 Original line number Diff line number Diff line Loading @@ -2934,6 +2934,8 @@ public class PackageInstaller { public int unarchiveId = -1; /** {@hide} */ public @Nullable String dexoptCompilerFilter = null; /** {@hide} */ public boolean forceVerification; private final ArrayMap<String, Integer> mPermissionStates; Loading Loading @@ -2988,6 +2990,7 @@ public class PackageInstaller { developmentInstallFlags = source.readInt(); unarchiveId = source.readInt(); dexoptCompilerFilter = source.readString(); forceVerification = source.readBoolean(); } /** {@hide} */ Loading Loading @@ -3024,6 +3027,7 @@ public class PackageInstaller { ret.developmentInstallFlags = developmentInstallFlags; ret.unarchiveId = unarchiveId; ret.dexoptCompilerFilter = dexoptCompilerFilter; ret.forceVerification = forceVerification; return ret; } Loading Loading @@ -3732,6 +3736,14 @@ public class PackageInstaller { return grantedPermissions.toArray(ArrayUtils.emptyArray(String.class)); } /** * Used by adb installations to force enable the verification for this install. * {@hide} */ public void setForceVerification() { this.forceVerification = true; } /** {@hide} */ public void dump(IndentingPrintWriter pw) { pw.printPair("mode", mode); Loading Loading @@ -3767,6 +3779,7 @@ public class PackageInstaller { pw.printHexPair("developmentInstallFlags", developmentInstallFlags); pw.printPair("unarchiveId", unarchiveId); pw.printPair("dexoptCompilerFilter", dexoptCompilerFilter); pw.printPair("forceVerification", forceVerification); pw.println(); } Loading Loading @@ -3813,6 +3826,7 @@ public class PackageInstaller { dest.writeInt(developmentInstallFlags); dest.writeInt(unarchiveId); dest.writeString(dexoptCompilerFilter); dest.writeBoolean(forceVerification); } public static final Parcelable.Creator<SessionParams> Loading
services/core/java/com/android/server/pm/PackageInstallerSession.java +49 −29 Original line number Diff line number Diff line Loading @@ -234,7 +234,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Predicate; import java.util.function.Supplier; public class PackageInstallerSession extends IPackageInstallerSession.Stub { private static final String TAG = "PackageInstallerSession"; Loading Loading @@ -1279,9 +1278,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } if (Flags.verificationService()) { if (shouldUseVerificationService()) { // Start binding to the verification service, if not bound already. mVerifierController.bindToVerifierServiceIfNeeded(() -> pm.snapshotComputer(), userId); mVerifierController.bindToVerifierServiceIfNeeded(mPm::snapshotComputer, userId); if (!TextUtils.isEmpty(params.appPackageName)) { mVerifierController.notifyPackageNameAvailable(params.appPackageName); } Loading Loading @@ -2875,9 +2874,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { setSessionFailed(e.error, errorMsg); onSessionVerificationFailure(e.error, errorMsg, /* extras= */ null); } if (Flags.verificationService()) { final Supplier<Computer> snapshotSupplier = mPm::snapshotComputer; if (mVerifierController.isVerifierInstalled(snapshotSupplier, userId)) { if (shouldUseVerificationService()) { final SigningInfo signingInfo; final List<SharedLibraryInfo> declaredLibraries; synchronized (mLock) { Loading @@ -2887,7 +2884,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } // Send the request to the verifier and wait for its response before the rest of // the installation can proceed. if (!mVerifierController.startVerificationSession(snapshotSupplier, userId, if (!mVerifierController.startVerificationSession(mPm::snapshotComputer, userId, sessionId, getPackageName(), Uri.fromFile(stageDir), signingInfo, declaredLibraries, mVerificationPolicy.get(), /* extensionParams= */ null, new VerifierCallback(), /* retry= */ false)) { Loading @@ -2897,13 +2894,36 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { /* extras= */ null); } } else { // Verifier is not installed. Let the installation pass for now. // No need to check with verifier. Proceed with the rest of the verification. resumeVerify(); } } else { // New verification feature is not enabled. Proceed to the rest of the verification. resumeVerify(); } private boolean shouldUseVerificationService() { if (!Flags.verificationService()) { // Feature is not enabled. return false; } if ((params.installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { // adb installs are exempted from verification unless explicitly requested if (!params.forceVerification) { return false; } } final String verifierPackageName = mVerifierController.getVerifierPackageName( mPm::snapshotComputer, userId); if (verifierPackageName == null) { // Feature is enabled but no verifier installed. return false; } synchronized (mLock) { if (verifierPackageName.equals(mPackageName)) { // The verifier itself is being updated. Skip. Slog.w(TAG, "Skipping verification service because the verifier is being updated"); return false; } } return true; } private void resumeVerify() { Loading Loading @@ -5597,7 +5617,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } catch (InstallerException ignored) { } if (Flags.verificationService() if (shouldUseVerificationService() && !TextUtils.isEmpty(params.appPackageName) && !isCommitted()) { // Only notify for the cancellation if the verification request has not Loading
services/core/java/com/android/server/pm/PackageManagerShellCommand.java +4 −0 Original line number Diff line number Diff line Loading @@ -3599,6 +3599,9 @@ class PackageManagerShellCommand extends ShellCommand { .setCompilerFilter(sessionParams.dexoptCompilerFilter) .build(); break; case "--force-verification": sessionParams.setForceVerification(); break; default: throw new IllegalArgumentException("Unknown option " + opt); } Loading Loading @@ -4805,6 +4808,7 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" https://source.android.com/docs/core/runtime/configure" + "#compiler_filters"); pw.println(" or 'skip'"); pw.println(" --force-verification: if set, enable the verification for this install"); pw.println(""); pw.println(" install-existing [--user USER_ID|all|current]"); pw.println(" [--instant] [--full] [--wait] [--restrict-permissions] PACKAGE"); Loading
services/core/java/com/android/server/pm/verify/pkg/VerificationStatusTracker.java +1 −11 Original line number Diff line number Diff line Loading @@ -30,9 +30,6 @@ public final class VerificationStatusTracker { private final @CurrentTimeMillisLong long mMaxTimeoutTime; @NonNull private final VerifierController.Injector mInjector; // Record the package name associated with the verification result @NonNull private final String mPackageName; /** * By default, the timeout time is the default timeout duration plus the current time (when Loading @@ -41,10 +38,8 @@ public final class VerificationStatusTracker { * can be extended via {@link #extendTimeRemaining} to the maximum allowed. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED) public VerificationStatusTracker(@NonNull String packageName, long defaultTimeoutMillis, long maxExtendedTimeoutMillis, public VerificationStatusTracker(long defaultTimeoutMillis, long maxExtendedTimeoutMillis, @NonNull VerifierController.Injector injector) { mPackageName = packageName; mStartTime = injector.getCurrentTimeMillis(); mTimeoutTime = mStartTime + defaultTimeoutMillis; mMaxTimeoutTime = mStartTime + maxExtendedTimeoutMillis; Loading Loading @@ -93,9 +88,4 @@ public final class VerificationStatusTracker { public boolean isTimeout() { return mInjector.getCurrentTimeMillis() >= mTimeoutTime; } @NonNull public String getPackageName() { return mPackageName; } }
services/core/java/com/android/server/pm/verify/pkg/VerifierController.java +14 −8 Original line number Diff line number Diff line Loading @@ -139,15 +139,16 @@ public class VerifierController { } /** * Used by the installation session to check if a verifier is installed. * Used by the installation session to get the package name of the installed verifier. */ public boolean isVerifierInstalled(Supplier<Computer> snapshotSupplier, int userId) { @Nullable public String getVerifierPackageName(Supplier<Computer> snapshotSupplier, int userId) { if (isVerifierConnected()) { // Verifier is connected or is being connected, so it must be installed. return true; return mRemoteServiceComponentName.getPackageName(); } // Verifier has been disconnected, or it hasn't been connected. Check if it's installed. return mInjector.isVerifierInstalled(snapshotSupplier.get(), userId); return mInjector.getVerifierPackageName(snapshotSupplier.get(), userId); } /** Loading Loading @@ -331,7 +332,7 @@ public class VerifierController { final long defaultTimeoutMillis = mInjector.getVerificationRequestTimeoutMillis(); final long maxExtendedTimeoutMillis = mInjector.getMaxVerificationExtendedTimeoutMillis(); final VerificationStatusTracker tracker = new VerificationStatusTracker( packageName, defaultTimeoutMillis, maxExtendedTimeoutMillis, mInjector); defaultTimeoutMillis, maxExtendedTimeoutMillis, mInjector); synchronized (mVerificationStatus) { mVerificationStatus.put(verificationId, tracker); } Loading Loading @@ -542,10 +543,15 @@ public class VerifierController { } /** * Check if a verifier is installed on this device. * Return the package name of the verifier installed on this device. */ public boolean isVerifierInstalled(Computer snapshot, int userId) { return resolveVerifierComponentName(snapshot, userId) != null; @Nullable public String getVerifierPackageName(Computer snapshot, int userId) { final ComponentName componentName = resolveVerifierComponentName(snapshot, userId); if (componentName == null) { return null; } return componentName.getPackageName(); } /** Loading