Loading core/java/android/content/pm/PackageInstaller.java +7 −0 Original line number Original line Diff line number Diff line Loading @@ -370,6 +370,13 @@ public class PackageInstaller { public static final String EXTRA_UNARCHIVE_ALL_USERS = public static final String EXTRA_UNARCHIVE_ALL_USERS = "android.content.pm.extra.UNARCHIVE_ALL_USERS"; "android.content.pm.extra.UNARCHIVE_ALL_USERS"; /** * A list of warnings that occurred during installation. * * @hide */ public static final String EXTRA_WARNINGS = "android.content.pm.extra.WARNINGS"; /** /** * Streaming installation pending. * Streaming installation pending. * Caller should make sure DataLoader is able to prepare image and reinitiate the operation. * Caller should make sure DataLoader is able to prepare image and reinitiate the operation. Loading services/core/java/com/android/server/pm/InstallRequest.java +43 −13 Original line number Original line Diff line number Diff line Loading @@ -22,6 +22,8 @@ import static android.content.pm.PackageManager.INSTALL_SCENARIO_DEFAULT; import static android.content.pm.PackageManager.INSTALL_SUCCEEDED; import static android.content.pm.PackageManager.INSTALL_SUCCEEDED; import static android.os.Process.INVALID_UID; import static android.os.Process.INVALID_UID; import static com.android.server.art.model.DexoptResult.DexContainerFileDexoptResult; import static com.android.server.art.model.DexoptResult.PackageDexoptResult; import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY; import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY; import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP; import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP; import static com.android.server.pm.PackageManagerService.TAG; import static com.android.server.pm.PackageManagerService.TAG; Loading Loading @@ -57,6 +59,7 @@ import com.android.server.pm.pkg.parsing.ParsingPackageUtils; import java.io.File; import java.io.File; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.List; import java.util.List; final class InstallRequest { final class InstallRequest { Loading Loading @@ -148,6 +151,9 @@ final class InstallRequest { @NonNull @NonNull private int[] mUpdateBroadcastInstantUserIds = EMPTY_INT_ARRAY; private int[] mUpdateBroadcastInstantUserIds = EMPTY_INT_ARRAY; @NonNull private ArrayList<String> mWarnings = new ArrayList<>(); // New install // New install InstallRequest(InstallingSession params) { InstallRequest(InstallingSession params) { mUserId = params.getUser().getIdentifier(); mUserId = params.getUser().getIdentifier(); Loading Loading @@ -658,6 +664,11 @@ final class InstallRequest { return mUpdateBroadcastInstantUserIds; return mUpdateBroadcastInstantUserIds; } } @NonNull public ArrayList<String> getWarnings() { return mWarnings; } public void setScanFlags(int scanFlags) { public void setScanFlags(int scanFlags) { mScanFlags = scanFlags; mScanFlags = scanFlags; } } Loading Loading @@ -855,6 +866,10 @@ final class InstallRequest { } } } } public void addWarning(@NonNull String warning) { mWarnings.add(warning); } public void onPrepareStarted() { public void onPrepareStarted() { if (mPackageMetrics != null) { if (mPackageMetrics != null) { mPackageMetrics.onStepStarted(PackageMetrics.STEP_PREPARE); mPackageMetrics.onStepStarted(PackageMetrics.STEP_PREPARE); Loading Loading @@ -904,23 +919,38 @@ final class InstallRequest { } } public void onDexoptFinished(DexoptResult dexoptResult) { public void onDexoptFinished(DexoptResult dexoptResult) { if (mPackageMetrics == null) { // Only report external profile warnings when installing from adb. The goal is to warn app return; // developers if they have provided bad external profiles, so it's not beneficial to report // those warnings in the normal app install workflow. if (isInstallFromAdb()) { var externalProfileErrors = new LinkedHashSet<String>(); for (PackageDexoptResult packageResult : dexoptResult.getPackageDexoptResults()) { for (DexContainerFileDexoptResult fileResult : packageResult.getDexContainerFileDexoptResults()) { externalProfileErrors.addAll(fileResult.getExternalProfileErrors()); } } mDexoptStatus = dexoptResult.getFinalStatus(); if (mDexoptStatus != DexoptResult.DEXOPT_PERFORMED) { return; } } if (!externalProfileErrors.isEmpty()) { addWarning("Error occurred during dexopt when processing external profiles:\n " + String.join("\n ", externalProfileErrors)); } } // Report dexopt metrics. if (mPackageMetrics != null) { mDexoptStatus = dexoptResult.getFinalStatus(); if (mDexoptStatus == DexoptResult.DEXOPT_PERFORMED) { long durationMillis = 0; long durationMillis = 0; for (DexoptResult.PackageDexoptResult packageResult : for (PackageDexoptResult packageResult : dexoptResult.getPackageDexoptResults()) { dexoptResult.getPackageDexoptResults()) { for (DexContainerFileDexoptResult fileResult : for (DexoptResult.DexContainerFileDexoptResult fileResult : packageResult.getDexContainerFileDexoptResults()) { packageResult.getDexContainerFileDexoptResults()) { durationMillis += fileResult.getDex2oatWallTimeMillis(); durationMillis += fileResult.getDex2oatWallTimeMillis(); } } } } mPackageMetrics.onStepFinished(PackageMetrics.STEP_DEXOPT, durationMillis); mPackageMetrics.onStepFinished(PackageMetrics.STEP_DEXOPT, durationMillis); } } } } public void onInstallCompleted() { public void onInstallCompleted() { if (getReturnCode() == INSTALL_SUCCEEDED) { if (getReturnCode() == INSTALL_SUCCEEDED) { Loading services/core/java/com/android/server/pm/PackageInstallerSession.java +4 −0 Original line number Original line Diff line number Diff line Loading @@ -5138,6 +5138,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { if (!TextUtils.isEmpty(existing)) { if (!TextUtils.isEmpty(existing)) { fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, existing); fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, existing); } } ArrayList<String> warnings = extras.getStringArrayList(PackageInstaller.EXTRA_WARNINGS); if (!ArrayUtils.isEmpty(warnings)) { fillIn.putStringArrayListExtra(PackageInstaller.EXTRA_WARNINGS, warnings); } } } try { try { final BroadcastOptions options = BroadcastOptions.makeBasic(); final BroadcastOptions options = BroadcastOptions.makeBasic(); Loading services/core/java/com/android/server/pm/PackageManagerService.java +3 −0 Original line number Original line Diff line number Diff line Loading @@ -1433,6 +1433,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService break; break; } } } } if (!request.getWarnings().isEmpty()) { extras.putStringArrayList(PackageInstaller.EXTRA_WARNINGS, request.getWarnings()); } return extras; return extras; } } Loading services/core/java/com/android/server/pm/PackageManagerShellCommand.java +14 −3 Original line number Original line Diff line number Diff line Loading @@ -4397,10 +4397,21 @@ class PackageManagerShellCommand extends ShellCommand { session.commit(receiver.getIntentSender()); session.commit(receiver.getIntentSender()); if (!session.isStaged()) { if (!session.isStaged()) { final Intent result = receiver.getResult(); final Intent result = receiver.getResult(); final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, int status = result.getIntExtra( PackageInstaller.STATUS_FAILURE); PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE); List<String> warnings = result.getStringArrayListExtra(PackageInstaller.EXTRA_WARNINGS); if (status == PackageInstaller.STATUS_SUCCESS) { if (status == PackageInstaller.STATUS_SUCCESS) { if (logSuccess) { if (!ArrayUtils.isEmpty(warnings)) { // Don't start the output string with "Success" because that will make adb // treat this as a success. for (String warning : warnings) { pw.println("Warning: " + warning); } // Treat warnings as failure to draw app developers' attention. status = PackageInstaller.STATUS_FAILURE; pw.println("Completed with warning(s)"); } else if (logSuccess) { pw.println("Success"); pw.println("Success"); } } } else { } else { Loading Loading
core/java/android/content/pm/PackageInstaller.java +7 −0 Original line number Original line Diff line number Diff line Loading @@ -370,6 +370,13 @@ public class PackageInstaller { public static final String EXTRA_UNARCHIVE_ALL_USERS = public static final String EXTRA_UNARCHIVE_ALL_USERS = "android.content.pm.extra.UNARCHIVE_ALL_USERS"; "android.content.pm.extra.UNARCHIVE_ALL_USERS"; /** * A list of warnings that occurred during installation. * * @hide */ public static final String EXTRA_WARNINGS = "android.content.pm.extra.WARNINGS"; /** /** * Streaming installation pending. * Streaming installation pending. * Caller should make sure DataLoader is able to prepare image and reinitiate the operation. * Caller should make sure DataLoader is able to prepare image and reinitiate the operation. Loading
services/core/java/com/android/server/pm/InstallRequest.java +43 −13 Original line number Original line Diff line number Diff line Loading @@ -22,6 +22,8 @@ import static android.content.pm.PackageManager.INSTALL_SCENARIO_DEFAULT; import static android.content.pm.PackageManager.INSTALL_SUCCEEDED; import static android.content.pm.PackageManager.INSTALL_SUCCEEDED; import static android.os.Process.INVALID_UID; import static android.os.Process.INVALID_UID; import static com.android.server.art.model.DexoptResult.DexContainerFileDexoptResult; import static com.android.server.art.model.DexoptResult.PackageDexoptResult; import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY; import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY; import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP; import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP; import static com.android.server.pm.PackageManagerService.TAG; import static com.android.server.pm.PackageManagerService.TAG; Loading Loading @@ -57,6 +59,7 @@ import com.android.server.pm.pkg.parsing.ParsingPackageUtils; import java.io.File; import java.io.File; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.List; import java.util.List; final class InstallRequest { final class InstallRequest { Loading Loading @@ -148,6 +151,9 @@ final class InstallRequest { @NonNull @NonNull private int[] mUpdateBroadcastInstantUserIds = EMPTY_INT_ARRAY; private int[] mUpdateBroadcastInstantUserIds = EMPTY_INT_ARRAY; @NonNull private ArrayList<String> mWarnings = new ArrayList<>(); // New install // New install InstallRequest(InstallingSession params) { InstallRequest(InstallingSession params) { mUserId = params.getUser().getIdentifier(); mUserId = params.getUser().getIdentifier(); Loading Loading @@ -658,6 +664,11 @@ final class InstallRequest { return mUpdateBroadcastInstantUserIds; return mUpdateBroadcastInstantUserIds; } } @NonNull public ArrayList<String> getWarnings() { return mWarnings; } public void setScanFlags(int scanFlags) { public void setScanFlags(int scanFlags) { mScanFlags = scanFlags; mScanFlags = scanFlags; } } Loading Loading @@ -855,6 +866,10 @@ final class InstallRequest { } } } } public void addWarning(@NonNull String warning) { mWarnings.add(warning); } public void onPrepareStarted() { public void onPrepareStarted() { if (mPackageMetrics != null) { if (mPackageMetrics != null) { mPackageMetrics.onStepStarted(PackageMetrics.STEP_PREPARE); mPackageMetrics.onStepStarted(PackageMetrics.STEP_PREPARE); Loading Loading @@ -904,23 +919,38 @@ final class InstallRequest { } } public void onDexoptFinished(DexoptResult dexoptResult) { public void onDexoptFinished(DexoptResult dexoptResult) { if (mPackageMetrics == null) { // Only report external profile warnings when installing from adb. The goal is to warn app return; // developers if they have provided bad external profiles, so it's not beneficial to report // those warnings in the normal app install workflow. if (isInstallFromAdb()) { var externalProfileErrors = new LinkedHashSet<String>(); for (PackageDexoptResult packageResult : dexoptResult.getPackageDexoptResults()) { for (DexContainerFileDexoptResult fileResult : packageResult.getDexContainerFileDexoptResults()) { externalProfileErrors.addAll(fileResult.getExternalProfileErrors()); } } mDexoptStatus = dexoptResult.getFinalStatus(); if (mDexoptStatus != DexoptResult.DEXOPT_PERFORMED) { return; } } if (!externalProfileErrors.isEmpty()) { addWarning("Error occurred during dexopt when processing external profiles:\n " + String.join("\n ", externalProfileErrors)); } } // Report dexopt metrics. if (mPackageMetrics != null) { mDexoptStatus = dexoptResult.getFinalStatus(); if (mDexoptStatus == DexoptResult.DEXOPT_PERFORMED) { long durationMillis = 0; long durationMillis = 0; for (DexoptResult.PackageDexoptResult packageResult : for (PackageDexoptResult packageResult : dexoptResult.getPackageDexoptResults()) { dexoptResult.getPackageDexoptResults()) { for (DexContainerFileDexoptResult fileResult : for (DexoptResult.DexContainerFileDexoptResult fileResult : packageResult.getDexContainerFileDexoptResults()) { packageResult.getDexContainerFileDexoptResults()) { durationMillis += fileResult.getDex2oatWallTimeMillis(); durationMillis += fileResult.getDex2oatWallTimeMillis(); } } } } mPackageMetrics.onStepFinished(PackageMetrics.STEP_DEXOPT, durationMillis); mPackageMetrics.onStepFinished(PackageMetrics.STEP_DEXOPT, durationMillis); } } } } public void onInstallCompleted() { public void onInstallCompleted() { if (getReturnCode() == INSTALL_SUCCEEDED) { if (getReturnCode() == INSTALL_SUCCEEDED) { Loading
services/core/java/com/android/server/pm/PackageInstallerSession.java +4 −0 Original line number Original line Diff line number Diff line Loading @@ -5138,6 +5138,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { if (!TextUtils.isEmpty(existing)) { if (!TextUtils.isEmpty(existing)) { fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, existing); fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, existing); } } ArrayList<String> warnings = extras.getStringArrayList(PackageInstaller.EXTRA_WARNINGS); if (!ArrayUtils.isEmpty(warnings)) { fillIn.putStringArrayListExtra(PackageInstaller.EXTRA_WARNINGS, warnings); } } } try { try { final BroadcastOptions options = BroadcastOptions.makeBasic(); final BroadcastOptions options = BroadcastOptions.makeBasic(); Loading
services/core/java/com/android/server/pm/PackageManagerService.java +3 −0 Original line number Original line Diff line number Diff line Loading @@ -1433,6 +1433,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService break; break; } } } } if (!request.getWarnings().isEmpty()) { extras.putStringArrayList(PackageInstaller.EXTRA_WARNINGS, request.getWarnings()); } return extras; return extras; } } Loading
services/core/java/com/android/server/pm/PackageManagerShellCommand.java +14 −3 Original line number Original line Diff line number Diff line Loading @@ -4397,10 +4397,21 @@ class PackageManagerShellCommand extends ShellCommand { session.commit(receiver.getIntentSender()); session.commit(receiver.getIntentSender()); if (!session.isStaged()) { if (!session.isStaged()) { final Intent result = receiver.getResult(); final Intent result = receiver.getResult(); final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, int status = result.getIntExtra( PackageInstaller.STATUS_FAILURE); PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE); List<String> warnings = result.getStringArrayListExtra(PackageInstaller.EXTRA_WARNINGS); if (status == PackageInstaller.STATUS_SUCCESS) { if (status == PackageInstaller.STATUS_SUCCESS) { if (logSuccess) { if (!ArrayUtils.isEmpty(warnings)) { // Don't start the output string with "Success" because that will make adb // treat this as a success. for (String warning : warnings) { pw.println("Warning: " + warning); } // Treat warnings as failure to draw app developers' attention. status = PackageInstaller.STATUS_FAILURE; pw.println("Completed with warning(s)"); } else if (logSuccess) { pw.println("Success"); pw.println("Success"); } } } else { } else { Loading