Merge "Avoid accidental shadowing in AGSL code." into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index f0b7598..f2cae097 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -13,6 +13,7 @@
// limitations under the License.
aconfig_srcjars = [
+ ":android.content.pm.flags-aconfig-java{.generated_srcjars}",
":android.hardware.biometrics.flags-aconfig-java{.generated_srcjars}",
":android.nfc.flags-aconfig-java{.generated_srcjars}",
":android.os.flags-aconfig-java{.generated_srcjars}",
@@ -145,6 +146,26 @@
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+// Package Manager
+aconfig_declarations {
+ name: "android.content.pm.flags-aconfig",
+ package: "android.content.pm",
+ srcs: ["core/java/android/content/pm/flags.aconfig"],
+}
+
+java_aconfig_library {
+ name: "android.content.pm.flags-aconfig-java",
+ aconfig_declarations: "android.content.pm.flags-aconfig",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
+java_aconfig_library {
+ name: "android.content.pm.flags-aconfig-java-host",
+ aconfig_declarations: "android.content.pm.flags-aconfig",
+ host_supported: true,
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
// Biometrics
aconfig_declarations {
name: "android.hardware.biometrics.flags-aconfig",
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index ef26235..f11b1b7 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -345,6 +345,13 @@
"android.content.pm.extra.RESOLVED_BASE_PATH";
/**
+ * A list of warnings that occurred during installation.
+ *
+ * @hide
+ */
+ public static final String EXTRA_WARNINGS = "android.content.pm.extra.WARNINGS";
+
+ /**
* Streaming installation pending.
* Caller should make sure DataLoader is able to prepare image and reinitiate the operation.
*
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
new file mode 100644
index 0000000..5242533
--- /dev/null
+++ b/core/java/android/content/pm/flags.aconfig
@@ -0,0 +1,8 @@
+package: "android.content.pm"
+
+flag {
+ name: "use_art_service_v2"
+ namespace: "package_manager_service"
+ description: "Feature flag to enable the features that rely on new ART Service APIs that are in the VIC version of the ART module."
+ bug: "304741685"
+}
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 94971b8..92be4c0 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -636,44 +636,33 @@
}
/**
- * Determine if ANGLE will be used and setup the environment
- */
- private boolean setupAndUseAngle(Context context, String packageName) {
- // Need to make sure we are evaluating ANGLE usage for the correct circumstances
- if (!setupAngle(context, null, context.getPackageManager(), packageName)) {
- Log.v(TAG, "Package '" + packageName + "' should not use ANGLE");
- return false;
- }
-
- final boolean useAngle = getShouldUseAngle(packageName);
- Log.v(TAG, "Package '" + packageName + "' should use ANGLE = '" + useAngle + "'");
-
- return useAngle;
- }
-
- /**
* Show the ANGLE in Use Dialog Box
* @param context
*/
public void showAngleInUseDialogBox(Context context) {
- final String packageName = context.getPackageName();
-
- if (shouldShowAngleInUseDialogBox(context) && setupAndUseAngle(context, packageName)) {
- final Intent intent = new Intent(ACTION_ANGLE_FOR_ANDROID_TOAST_MESSAGE);
- String anglePkg = getAnglePackageName(context.getPackageManager());
- intent.setPackage(anglePkg);
-
- context.sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- Bundle results = getResultExtras(true);
-
- String toastMsg = results.getString(INTENT_KEY_A4A_TOAST_MESSAGE);
- final Toast toast = Toast.makeText(context, toastMsg, Toast.LENGTH_LONG);
- toast.show();
- }
- }, null, Activity.RESULT_OK, null, null);
+ if (!shouldShowAngleInUseDialogBox(context)) {
+ return;
}
+
+ final String packageName = context.getPackageName();
+ if (!getShouldUseAngle(packageName)) {
+ return;
+ }
+
+ final Intent intent = new Intent(ACTION_ANGLE_FOR_ANDROID_TOAST_MESSAGE);
+ final String anglePkg = getAnglePackageName(context.getPackageManager());
+ intent.setPackage(anglePkg);
+
+ context.sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final Bundle results = getResultExtras(true);
+
+ final String toastMsg = results.getString(INTENT_KEY_A4A_TOAST_MESSAGE);
+ final Toast toast = Toast.makeText(context, toastMsg, Toast.LENGTH_LONG);
+ toast.show();
+ }
+ }, null, Activity.RESULT_OK, null, null);
}
private String[] getAngleEglFeatures(Context context, Bundle coreSettings) {
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index ceb3858..b002bbf 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -1282,10 +1282,8 @@
* {@link AudioFormat#CHANNEL_OUT_BACK_CENTER},
* {@link AudioFormat#CHANNEL_OUT_SIDE_LEFT},
* {@link AudioFormat#CHANNEL_OUT_SIDE_RIGHT}.
- * <p> For a valid {@link AudioTrack} channel position mask,
- * the following conditions apply:
- * <br> (1) at most eight channel positions may be used;
- * <br> (2) right/left pairs should be matched.
+ * <p> For output or {@link AudioTrack}, channel position masks which do not contain
+ * matched left/right pairs are invalid.
* <p> For input or {@link AudioRecord}, the mask should be
* {@link AudioFormat#CHANNEL_IN_MONO} or
* {@link AudioFormat#CHANNEL_IN_STEREO}. {@link AudioFormat#CHANNEL_IN_MONO} is
diff --git a/services/core/java/com/android/server/os/NativeTombstoneManager.java b/services/core/java/com/android/server/os/NativeTombstoneManager.java
index 7b0eddc..e5616d0 100644
--- a/services/core/java/com/android/server/os/NativeTombstoneManager.java
+++ b/services/core/java/com/android/server/os/NativeTombstoneManager.java
@@ -567,6 +567,10 @@
@Override
public void onEvent(int event, @Nullable String path) {
+ if (path == null) {
+ Slog.w(TAG, "path is null at TombstoneWatcher.onEvent()");
+ return;
+ }
mHandler.post(() -> {
// Ignore .tmp files.
if (path.endsWith(".tmp")) {
diff --git a/services/core/java/com/android/server/pm/InstallRequest.java b/services/core/java/com/android/server/pm/InstallRequest.java
index 6fc14e8..046dcc2 100644
--- a/services/core/java/com/android/server/pm/InstallRequest.java
+++ b/services/core/java/com/android/server/pm/InstallRequest.java
@@ -22,6 +22,8 @@
import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
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.SCAN_AS_INSTANT_APP;
import static com.android.server.pm.PackageManagerService.TAG;
@@ -30,6 +32,7 @@
import android.apex.ApexInfo;
import android.app.AppOpsManager;
import android.content.pm.DataLoaderType;
+import android.content.pm.Flags;
import android.content.pm.IPackageInstallObserver2;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
@@ -52,6 +55,7 @@
import java.io.File;
import java.util.ArrayList;
+import java.util.LinkedHashSet;
import java.util.List;
final class InstallRequest {
@@ -130,6 +134,9 @@
private int mDexoptStatus;
+ @NonNull
+ private ArrayList<String> mWarnings = new ArrayList<>();
+
// New install
InstallRequest(InstallingSession params) {
mUserId = params.getUser().getIdentifier();
@@ -615,6 +622,11 @@
return mDexoptStatus;
}
+ @NonNull
+ public ArrayList<String> getWarnings() {
+ return mWarnings;
+ }
+
public void setScanFlags(int scanFlags) {
mScanFlags = scanFlags;
}
@@ -757,6 +769,10 @@
}
}
+ public void addWarning(@NonNull String warning) {
+ mWarnings.add(warning);
+ }
+
public void onPrepareStarted() {
if (mPackageMetrics != null) {
mPackageMetrics.onStepStarted(PackageMetrics.STEP_PREPARE);
@@ -806,22 +822,37 @@
}
public void onDexoptFinished(DexoptResult dexoptResult) {
- if (mPackageMetrics == null) {
- return;
- }
- mDexoptStatus = dexoptResult.getFinalStatus();
- if (mDexoptStatus != DexoptResult.DEXOPT_PERFORMED) {
- return;
- }
- long durationMillis = 0;
- for (DexoptResult.PackageDexoptResult packageResult :
- dexoptResult.getPackageDexoptResults()) {
- for (DexoptResult.DexContainerFileDexoptResult fileResult :
- packageResult.getDexContainerFileDexoptResults()) {
- durationMillis += fileResult.getDex2oatWallTimeMillis();
+ // Only report external profile warnings when installing from adb. The goal is to warn app
+ // 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() && Flags.useArtServiceV2()) {
+ var externalProfileErrors = new LinkedHashSet<String>();
+ for (PackageDexoptResult packageResult : dexoptResult.getPackageDexoptResults()) {
+ for (DexContainerFileDexoptResult fileResult :
+ packageResult.getDexContainerFileDexoptResults()) {
+ externalProfileErrors.addAll(fileResult.getExternalProfileErrors());
+ }
+ }
+ if (!externalProfileErrors.isEmpty()) {
+ addWarning("Error occurred during dexopt when processing external profiles:\n "
+ + String.join("\n ", externalProfileErrors));
}
}
- mPackageMetrics.onStepFinished(PackageMetrics.STEP_DEXOPT, durationMillis);
+
+ // Report dexopt metrics.
+ if (mPackageMetrics != null) {
+ mDexoptStatus = dexoptResult.getFinalStatus();
+ if (mDexoptStatus == DexoptResult.DEXOPT_PERFORMED) {
+ long durationMillis = 0;
+ for (PackageDexoptResult packageResult : dexoptResult.getPackageDexoptResults()) {
+ for (DexContainerFileDexoptResult fileResult :
+ packageResult.getDexContainerFileDexoptResults()) {
+ durationMillis += fileResult.getDex2oatWallTimeMillis();
+ }
+ }
+ mPackageMetrics.onStepFinished(PackageMetrics.STEP_DEXOPT, durationMillis);
+ }
+ }
}
public void onInstallCompleted() {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index f0e3895..3e72fe4 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -2714,15 +2714,40 @@
* @return a future that will be completed when the whole process is completed.
*/
private CompletableFuture<Void> install() {
+ // `futures` either contains only one session (`this`) or contains one parent session
+ // (`this`) and n-1 child sessions.
List<CompletableFuture<InstallResult>> futures = installNonStaged();
CompletableFuture<InstallResult>[] arr = new CompletableFuture[futures.size()];
return CompletableFuture.allOf(futures.toArray(arr)).whenComplete((r, t) -> {
if (t == null) {
setSessionApplied();
+ var multiPackageWarnings = new ArrayList<String>();
+ if (isMultiPackage()) {
+ // This is a parent session. Collect warnings from children.
+ for (CompletableFuture<InstallResult> f : futures) {
+ InstallResult result = f.join();
+ if (result.session != this && result.extras != null) {
+ ArrayList<String> childWarnings = result.extras.getStringArrayList(
+ PackageInstaller.EXTRA_WARNINGS);
+ if (!ArrayUtils.isEmpty(childWarnings)) {
+ multiPackageWarnings.addAll(childWarnings);
+ }
+ }
+ }
+ }
for (CompletableFuture<InstallResult> f : futures) {
InstallResult result = f.join();
+ Bundle extras = result.extras;
+ if (isMultiPackage() && result.session == this
+ && !multiPackageWarnings.isEmpty()) {
+ if (extras == null) {
+ extras = new Bundle();
+ }
+ extras.putStringArrayList(
+ PackageInstaller.EXTRA_WARNINGS, multiPackageWarnings);
+ }
result.session.dispatchSessionFinished(
- INSTALL_SUCCEEDED, "Session installed", result.extras);
+ INSTALL_SUCCEEDED, "Session installed", extras);
}
} else {
PackageManagerException e = (PackageManagerException) t.getCause();
@@ -4904,6 +4929,10 @@
if (!TextUtils.isEmpty(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 {
final BroadcastOptions options = BroadcastOptions.makeBasic();
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index f2b62ea..20bd56d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1415,6 +1415,9 @@
break;
}
}
+ if (!request.getWarnings().isEmpty()) {
+ extras.putStringArrayList(PackageInstaller.EXTRA_WARNINGS, request.getWarnings());
+ }
return extras;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 2a7ebfb..2327b85 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -3982,10 +3982,21 @@
session.commit(receiver.getIntentSender());
if (!session.isStaged()) {
final Intent result = receiver.getResult();
- final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
- PackageInstaller.STATUS_FAILURE);
+ int status = result.getIntExtra(
+ PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE);
+ List<String> warnings =
+ result.getStringArrayListExtra(PackageInstaller.EXTRA_WARNINGS);
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");
}
} else {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index f6fa51e..18a6254 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -8225,7 +8225,11 @@
private void clearSizeCompatModeAttributes() {
mInSizeCompatModeForBounds = false;
+ final float lastSizeCompatScale = mSizeCompatScale;
mSizeCompatScale = 1f;
+ if (mSizeCompatScale != lastSizeCompatScale) {
+ forAllWindows(WindowState::updateGlobalScale, false /* traverseTopToBottom */);
+ }
mSizeCompatBounds = null;
mCompatDisplayInsets = null;
mLetterboxUiController.clearInheritedCompatDisplayInsets();
@@ -8233,11 +8237,7 @@
@VisibleForTesting
void clearSizeCompatMode() {
- final float lastSizeCompatScale = mSizeCompatScale;
clearSizeCompatModeAttributes();
- if (mSizeCompatScale != lastSizeCompatScale) {
- forAllWindows(WindowState::updateGlobalScale, false /* traverseTopToBottom */);
- }
// Clear config override in #updateCompatDisplayInsets().
final int activityType = getActivityType();
final Configuration overrideConfig = getRequestedOverrideConfiguration();