summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt1
-rw-r--r--core/java/android/app/ApplicationStartInfo.java89
-rw-r--r--core/java/android/hardware/input/InputSettings.java4
-rw-r--r--core/java/android/view/ViewRootImpl.java20
-rw-r--r--core/java/android/view/flags/refresh_rate_flags.aconfig7
-rw-r--r--graphics/java/android/graphics/RuntimeShader.java39
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PhonePipKeepClearAlgorithmTest.java (renamed from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithmTest.java)7
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PhoneSizeSpecSourceTest.java (renamed from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhoneSizeSpecSourceTest.java)7
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsAlgorithmTest.java (renamed from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java)11
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsStateTest.java (renamed from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java)8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDoubleTapHelperTest.java (renamed from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipDoubleTapHelperTest.java)6
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipSnapAlgorithmTest.java (renamed from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipSnapAlgorithmTest.java)6
-rw-r--r--libs/hwui/aconfig/hwui_flags.aconfig8
-rw-r--r--libs/hwui/jni/Shader.cpp10
-rw-r--r--ravenwood/runtime-jni/ravenwood_initializer.cpp77
-rw-r--r--services/core/java/com/android/server/am/AppStartInfoTracker.java40
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java11
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java26
18 files changed, 231 insertions, 146 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index fde139b60ca5..339671f5b17c 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -17621,7 +17621,6 @@ package android.graphics {
method public void setIntUniform(@NonNull String, int, int, int);
method public void setIntUniform(@NonNull String, int, int, int, int);
method public void setIntUniform(@NonNull String, @NonNull int[]);
- method @FlaggedApi("com.android.graphics.hwui.flags.shader_color_space") public void setWorkingColorSpace(@Nullable android.graphics.ColorSpace);
}
@FlaggedApi("com.android.graphics.hwui.flags.runtime_color_filters_blenders") public class RuntimeXfermode extends android.graphics.Xfermode {
diff --git a/core/java/android/app/ApplicationStartInfo.java b/core/java/android/app/ApplicationStartInfo.java
index 3214bd8f01fc..2e8031dd22fe 100644
--- a/core/java/android/app/ApplicationStartInfo.java
+++ b/core/java/android/app/ApplicationStartInfo.java
@@ -840,7 +840,9 @@ public final class ApplicationStartInfo implements Parcelable {
* @hide
*/
// LINT.IfChange(write_proto)
- public void writeToProto(ProtoOutputStream proto, long fieldId) throws IOException {
+ public void writeToProto(ProtoOutputStream proto, long fieldId,
+ ByteArrayOutputStream byteArrayOutputStream, ObjectOutputStream objectOutputStream,
+ TypedXmlSerializer typedXmlSerializer) throws IOException {
final long token = proto.start(fieldId);
proto.write(ApplicationStartInfoProto.PID, mPid);
proto.write(ApplicationStartInfoProto.REAL_UID, mRealUid);
@@ -850,38 +852,38 @@ public final class ApplicationStartInfo implements Parcelable {
proto.write(ApplicationStartInfoProto.STARTUP_STATE, mStartupState);
proto.write(ApplicationStartInfoProto.REASON, mReason);
if (mStartupTimestampsNs != null && mStartupTimestampsNs.size() > 0) {
- ByteArrayOutputStream timestampsBytes = new ByteArrayOutputStream();
- ObjectOutputStream timestampsOut = new ObjectOutputStream(timestampsBytes);
- TypedXmlSerializer serializer = Xml.resolveSerializer(timestampsOut);
- serializer.startDocument(null, true);
- serializer.startTag(null, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMPS);
+ byteArrayOutputStream = new ByteArrayOutputStream();
+ objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
+ typedXmlSerializer = Xml.resolveSerializer(objectOutputStream);
+ typedXmlSerializer.startDocument(null, true);
+ typedXmlSerializer.startTag(null, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMPS);
for (int i = 0; i < mStartupTimestampsNs.size(); i++) {
- serializer.startTag(null, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMP);
- serializer.attributeInt(null, PROTO_SERIALIZER_ATTRIBUTE_KEY,
+ typedXmlSerializer.startTag(null, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMP);
+ typedXmlSerializer.attributeInt(null, PROTO_SERIALIZER_ATTRIBUTE_KEY,
mStartupTimestampsNs.keyAt(i));
- serializer.attributeLong(null, PROTO_SERIALIZER_ATTRIBUTE_TS,
+ typedXmlSerializer.attributeLong(null, PROTO_SERIALIZER_ATTRIBUTE_TS,
mStartupTimestampsNs.valueAt(i));
- serializer.endTag(null, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMP);
+ typedXmlSerializer.endTag(null, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMP);
}
- serializer.endTag(null, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMPS);
- serializer.endDocument();
+ typedXmlSerializer.endTag(null, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMPS);
+ typedXmlSerializer.endDocument();
proto.write(ApplicationStartInfoProto.STARTUP_TIMESTAMPS,
- timestampsBytes.toByteArray());
- timestampsOut.close();
+ byteArrayOutputStream.toByteArray());
+ objectOutputStream.close();
}
proto.write(ApplicationStartInfoProto.START_TYPE, mStartType);
if (mStartIntent != null) {
- ByteArrayOutputStream intentBytes = new ByteArrayOutputStream();
- ObjectOutputStream intentOut = new ObjectOutputStream(intentBytes);
- TypedXmlSerializer serializer = Xml.resolveSerializer(intentOut);
- serializer.startDocument(null, true);
- serializer.startTag(null, PROTO_SERIALIZER_ATTRIBUTE_INTENT);
- mStartIntent.saveToXml(serializer);
- serializer.endTag(null, PROTO_SERIALIZER_ATTRIBUTE_INTENT);
- serializer.endDocument();
+ byteArrayOutputStream = new ByteArrayOutputStream();
+ objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
+ typedXmlSerializer = Xml.resolveSerializer(objectOutputStream);
+ typedXmlSerializer.startDocument(null, true);
+ typedXmlSerializer.startTag(null, PROTO_SERIALIZER_ATTRIBUTE_INTENT);
+ mStartIntent.saveToXml(typedXmlSerializer);
+ typedXmlSerializer.endTag(null, PROTO_SERIALIZER_ATTRIBUTE_INTENT);
+ typedXmlSerializer.endDocument();
proto.write(ApplicationStartInfoProto.START_INTENT,
- intentBytes.toByteArray());
- intentOut.close();
+ byteArrayOutputStream.toByteArray());
+ objectOutputStream.close();
}
proto.write(ApplicationStartInfoProto.LAUNCH_MODE, mLaunchMode);
proto.write(ApplicationStartInfoProto.WAS_FORCE_STOPPED, mWasForceStopped);
@@ -900,7 +902,9 @@ public final class ApplicationStartInfo implements Parcelable {
* @hide
*/
// LINT.IfChange(read_proto)
- public void readFromProto(ProtoInputStream proto, long fieldId)
+ public void readFromProto(ProtoInputStream proto, long fieldId,
+ ByteArrayInputStream byteArrayInputStream, ObjectInputStream objectInputStream,
+ TypedXmlPullParser typedXmlPullParser)
throws IOException, WireTypeMismatchException, ClassNotFoundException {
final long token = proto.start(fieldId);
while (proto.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
@@ -927,19 +931,21 @@ public final class ApplicationStartInfo implements Parcelable {
mReason = proto.readInt(ApplicationStartInfoProto.REASON);
break;
case (int) ApplicationStartInfoProto.STARTUP_TIMESTAMPS:
- ByteArrayInputStream timestampsBytes = new ByteArrayInputStream(proto.readBytes(
+ byteArrayInputStream = new ByteArrayInputStream(proto.readBytes(
ApplicationStartInfoProto.STARTUP_TIMESTAMPS));
- ObjectInputStream timestampsIn = new ObjectInputStream(timestampsBytes);
+ objectInputStream = new ObjectInputStream(byteArrayInputStream);
mStartupTimestampsNs = new ArrayMap<Integer, Long>();
try {
- TypedXmlPullParser parser = Xml.resolvePullParser(timestampsIn);
- XmlUtils.beginDocument(parser, PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMPS);
- int depth = parser.getDepth();
- while (XmlUtils.nextElementWithin(parser, depth)) {
- if (PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMP.equals(parser.getName())) {
- int key = parser.getAttributeInt(null,
+ typedXmlPullParser = Xml.resolvePullParser(objectInputStream);
+ XmlUtils.beginDocument(typedXmlPullParser,
+ PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMPS);
+ int depth = typedXmlPullParser.getDepth();
+ while (XmlUtils.nextElementWithin(typedXmlPullParser, depth)) {
+ if (PROTO_SERIALIZER_ATTRIBUTE_TIMESTAMP.equals(
+ typedXmlPullParser.getName())) {
+ int key = typedXmlPullParser.getAttributeInt(null,
PROTO_SERIALIZER_ATTRIBUTE_KEY);
- long ts = parser.getAttributeLong(null,
+ long ts = typedXmlPullParser.getAttributeLong(null,
PROTO_SERIALIZER_ATTRIBUTE_TS);
mStartupTimestampsNs.put(key, ts);
}
@@ -947,23 +953,24 @@ public final class ApplicationStartInfo implements Parcelable {
} catch (XmlPullParserException e) {
// Timestamps lost
}
- timestampsIn.close();
+ objectInputStream.close();
break;
case (int) ApplicationStartInfoProto.START_TYPE:
mStartType = proto.readInt(ApplicationStartInfoProto.START_TYPE);
break;
case (int) ApplicationStartInfoProto.START_INTENT:
- ByteArrayInputStream intentBytes = new ByteArrayInputStream(proto.readBytes(
+ byteArrayInputStream = new ByteArrayInputStream(proto.readBytes(
ApplicationStartInfoProto.START_INTENT));
- ObjectInputStream intentIn = new ObjectInputStream(intentBytes);
+ objectInputStream = new ObjectInputStream(byteArrayInputStream);
try {
- TypedXmlPullParser parser = Xml.resolvePullParser(intentIn);
- XmlUtils.beginDocument(parser, PROTO_SERIALIZER_ATTRIBUTE_INTENT);
- mStartIntent = Intent.restoreFromXml(parser);
+ typedXmlPullParser = Xml.resolvePullParser(objectInputStream);
+ XmlUtils.beginDocument(typedXmlPullParser,
+ PROTO_SERIALIZER_ATTRIBUTE_INTENT);
+ mStartIntent = Intent.restoreFromXml(typedXmlPullParser);
} catch (XmlPullParserException e) {
// Intent lost
}
- intentIn.close();
+ objectInputStream.close();
break;
case (int) ApplicationStartInfoProto.LAUNCH_MODE:
mLaunchMode = proto.readInt(ApplicationStartInfoProto.LAUNCH_MODE);
diff --git a/core/java/android/hardware/input/InputSettings.java b/core/java/android/hardware/input/InputSettings.java
index 3d4b8854b01f..7c82abe083c2 100644
--- a/core/java/android/hardware/input/InputSettings.java
+++ b/core/java/android/hardware/input/InputSettings.java
@@ -386,7 +386,7 @@ public class InputSettings {
*/
public static boolean isTouchpadAccelerationEnabled(@NonNull Context context) {
if (!isPointerAccelerationFeatureFlagEnabled()) {
- return false;
+ return true;
}
return Settings.System.getIntForUser(context.getContentResolver(),
@@ -833,7 +833,7 @@ public class InputSettings {
*/
public static boolean isMousePointerAccelerationEnabled(@NonNull Context context) {
if (!isPointerAccelerationFeatureFlagEnabled()) {
- return false;
+ return true;
}
return Settings.System.getIntForUser(context.getContentResolver(),
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index de3e45b8ebde..6b6147a3749d 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -118,6 +118,7 @@ import static android.view.flags.Flags.addSchandleToVriSurface;
import static android.view.flags.Flags.disableDrawWakeLock;
import static android.view.flags.Flags.sensitiveContentAppProtection;
import static android.view.flags.Flags.sensitiveContentPrematureProtectionRemovedFix;
+import static android.view.flags.Flags.toolkitFrameRateDebug;
import static android.view.flags.Flags.toolkitFrameRateFunctionEnablingReadOnly;
import static android.view.flags.Flags.toolkitFrameRateTouchBoost25q1;
import static android.view.flags.Flags.toolkitFrameRateTypingReadOnly;
@@ -1227,6 +1228,7 @@ public final class ViewRootImpl implements ViewParent,
com.android.graphics.surfaceflinger.flags.Flags.vrrBugfix24q4();
private static final boolean sEnableVrr = ViewProperties.vrr_enabled().orElse(true);
private static final boolean sToolkitInitialTouchBoostFlagValue = toolkitInitialTouchBoost();
+ private static boolean sToolkitFrameRateDebugFlagValue = toolkitFrameRateDebug();
static {
sToolkitSetFrameRateReadOnlyFlagValue = toolkitSetFrameRateReadOnly();
@@ -13139,6 +13141,11 @@ public final class ViewRootImpl implements ViewParent,
if (sToolkitFrameRateFunctionEnablingReadOnlyFlagValue) {
mFrameRateTransaction.setFrameRateCategory(mSurfaceControl,
frameRateCategory, false).applyAsyncUnsafe();
+
+ if (sToolkitFrameRateDebugFlagValue) {
+ Log.v(mTag, "### ViewRootImpl setFrameRateCategory '"
+ + categoryToString(frameRateCategory) + "'");
+ }
}
mLastPreferredFrameRateCategory = frameRateCategory;
}
@@ -13201,8 +13208,15 @@ public final class ViewRootImpl implements ViewParent,
if (preferredFrameRate > 0) {
mFrameRateTransaction.setFrameRate(mSurfaceControl, preferredFrameRate,
mFrameRateCompatibility);
+ if (sToolkitFrameRateDebugFlagValue) {
+ Log.v(mTag, "### ViewRootImpl setFrameRate '"
+ + preferredFrameRate + "'");
+ }
} else {
mFrameRateTransaction.clearFrameRate(mSurfaceControl);
+ if (sToolkitFrameRateDebugFlagValue) {
+ Log.v(mTag, "### ViewRootImpl setFrameRate 0 Hz");
+ }
}
mFrameRateTransaction.applyAsyncUnsafe();
}
@@ -13256,6 +13270,12 @@ public final class ViewRootImpl implements ViewParent,
// mFrameRateCategoryView = view == null ? "-" : view.getClass().getSimpleName();
}
mDrawnThisFrame = true;
+
+ if (sToolkitFrameRateDebugFlagValue) {
+ String viewName = view == null ? "-" : view.getClass().getSimpleName();
+ Log.v(mTag, "### View: " + viewName + " votes '"
+ + categoryToString(frameRateCategory) + "'");
+ }
}
/**
diff --git a/core/java/android/view/flags/refresh_rate_flags.aconfig b/core/java/android/view/flags/refresh_rate_flags.aconfig
index 3bc2205f8e1c..18fa0f353f36 100644
--- a/core/java/android/view/flags/refresh_rate_flags.aconfig
+++ b/core/java/android/view/flags/refresh_rate_flags.aconfig
@@ -143,4 +143,11 @@ flag {
namespace: "toolkit"
description: "Feature flag to update initial touch boost logic"
bug: "393004744"
+}
+
+flag {
+ name: "toolkit_frame_rate_debug"
+ namespace: "toolkit"
+ description: "Feature flag to ennable ARR debug message"
+ bug: "394614443"
} \ No newline at end of file
diff --git a/graphics/java/android/graphics/RuntimeShader.java b/graphics/java/android/graphics/RuntimeShader.java
index 9016724b765e..3543e991924e 100644
--- a/graphics/java/android/graphics/RuntimeShader.java
+++ b/graphics/java/android/graphics/RuntimeShader.java
@@ -20,7 +20,6 @@ import android.annotation.ColorInt;
import android.annotation.ColorLong;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.util.ArrayMap;
import android.view.Window;
@@ -77,7 +76,6 @@ import libcore.util.NativeAllocationRegistry;
* Additionally, if the shader is invoked by another using {@link #setInputShader(String, Shader)},
* then that parent shader may modify the input coordinates arbitrarily.</p>
*
- * <a id="agsl-and-color-spaces"/>
* <h3>AGSL and Color Spaces</h3>
* <p>Android Graphics and by extension {@link RuntimeShader} are color managed. The working
* {@link ColorSpace} for an AGSL shader is defined to be the color space of the destination, which
@@ -269,8 +267,6 @@ public class RuntimeShader extends Shader {
private ArrayMap<String, ColorFilter> mColorFilterUniforms = new ArrayMap<>();
private ArrayMap<String, RuntimeXfermode> mXfermodeUniforms = new ArrayMap<>();
- private ColorSpace mWorkingColorSpace = null;
-
/**
* Creates a new RuntimeShader.
@@ -290,35 +286,6 @@ public class RuntimeShader extends Shader {
}
/**
- * Sets the working color space for this shader. That is, the shader will be evaluated
- * in the given colorspace before being converted to the output destination's colorspace.
- *
- * <p>By default the RuntimeShader is evaluated in the context of the
- * <a href="#agsl-and-color-spaces">destination colorspace</a>. By calling this method
- * that can be overridden to force the shader to be evaluated in the given colorspace first
- * before then being color converted to the destination colorspace.</p>
- *
- * @param colorSpace The ColorSpace to evaluate in. Must be an {@link ColorSpace#getModel() RGB}
- * ColorSpace. Passing null restores default behavior of working in the
- * destination colorspace.
- * @throws IllegalArgumentException If the colorspace is not RGB
- */
- @FlaggedApi(Flags.FLAG_SHADER_COLOR_SPACE)
- public void setWorkingColorSpace(@Nullable ColorSpace colorSpace) {
- if (colorSpace != null && colorSpace.getModel() != ColorSpace.Model.RGB) {
- throw new IllegalArgumentException("ColorSpace must be RGB, given " + colorSpace);
- }
- if (mWorkingColorSpace != colorSpace) {
- mWorkingColorSpace = colorSpace;
- if (mWorkingColorSpace != null) {
- // Just to enforce this can be resolved instead of erroring out later
- mWorkingColorSpace.getNativeInstance();
- }
- discardNativeInstance();
- }
- }
-
- /**
* Sets the uniform color value corresponding to this shader. If the shader does not have a
* uniform with that name or if the uniform is declared with a type other than vec3 or vec4 and
* corresponding layout(color) annotation then an IllegalArgumentException is thrown.
@@ -611,8 +578,7 @@ public class RuntimeShader extends Shader {
/** @hide */
@Override
protected long createNativeInstance(long nativeMatrix, boolean filterFromPaint) {
- return nativeCreateShader(mNativeInstanceRuntimeShaderBuilder, nativeMatrix,
- mWorkingColorSpace != null ? mWorkingColorSpace.getNativeInstance() : 0);
+ return nativeCreateShader(mNativeInstanceRuntimeShaderBuilder, nativeMatrix);
}
/** @hide */
@@ -622,8 +588,7 @@ public class RuntimeShader extends Shader {
private static native long nativeGetFinalizer();
private static native long nativeCreateBuilder(String agsl);
- private static native long nativeCreateShader(long shaderBuilder, long matrix,
- long colorSpacePtr);
+ private static native long nativeCreateShader(long shaderBuilder, long matrix);
private static native void nativeUpdateUniforms(
long shaderBuilder, String uniformName, float[] uniforms, boolean isColor);
private static native void nativeUpdateUniforms(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithmTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PhonePipKeepClearAlgorithmTest.java
index e3798e92c092..a6c35f1bd93c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithmTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PhonePipKeepClearAlgorithmTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.pip.phone;
+package com.android.wm.shell.common.pip;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -29,9 +29,6 @@ import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
import com.android.wm.shell.ShellTestCase;
-import com.android.wm.shell.common.pip.PhonePipKeepClearAlgorithm;
-import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
-import com.android.wm.shell.common.pip.PipBoundsState;
import org.junit.Before;
import org.junit.Test;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhoneSizeSpecSourceTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PhoneSizeSpecSourceTest.java
index 85f1da5322ea..737735c9efcd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhoneSizeSpecSourceTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PhoneSizeSpecSourceTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.pip.phone;
+package com.android.wm.shell.common.pip;
import static org.mockito.Mockito.when;
@@ -27,9 +27,6 @@ import android.view.DisplayInfo;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.DisplayLayout;
-import com.android.wm.shell.common.pip.PhoneSizeSpecSource;
-import com.android.wm.shell.common.pip.PipDisplayLayoutState;
-import com.android.wm.shell.common.pip.SizeSpecSource;
import org.junit.Assert;
import org.junit.Before;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsAlgorithmTest.java
index 080b0ae006ea..6bda2259b44c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsAlgorithmTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.pip;
+package com.android.wm.shell.common.pip;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -32,13 +32,6 @@ import androidx.test.filters.SmallTest;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.DisplayLayout;
-import com.android.wm.shell.common.pip.PhoneSizeSpecSource;
-import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
-import com.android.wm.shell.common.pip.PipBoundsState;
-import com.android.wm.shell.common.pip.PipDisplayLayoutState;
-import com.android.wm.shell.common.pip.PipKeepClearAlgorithmInterface;
-import com.android.wm.shell.common.pip.PipSnapAlgorithm;
-import com.android.wm.shell.common.pip.SizeSpecSource;
import org.junit.Before;
import org.junit.Test;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsStateTest.java
index 304da75f870c..ad664acfdc37 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsStateTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.pip;
+package com.android.wm.shell.common.pip;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -36,10 +36,6 @@ import androidx.test.filters.SmallTest;
import com.android.internal.util.function.TriConsumer;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTestCase;
-import com.android.wm.shell.common.pip.PhoneSizeSpecSource;
-import com.android.wm.shell.common.pip.PipBoundsState;
-import com.android.wm.shell.common.pip.PipDisplayLayoutState;
-import com.android.wm.shell.common.pip.SizeSpecSource;
import org.junit.Before;
import org.junit.Test;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipDoubleTapHelperTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDoubleTapHelperTest.java
index b583acda1c9a..1756aad8fc9b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipDoubleTapHelperTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDoubleTapHelperTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.pip.phone;
+package com.android.wm.shell.common.pip;
import static com.android.wm.shell.common.pip.PipDoubleTapHelper.SIZE_SPEC_CUSTOM;
import static com.android.wm.shell.common.pip.PipDoubleTapHelper.SIZE_SPEC_DEFAULT;
@@ -29,8 +29,6 @@ import android.graphics.Rect;
import android.testing.AndroidTestingRunner;
import com.android.wm.shell.ShellTestCase;
-import com.android.wm.shell.common.pip.PipBoundsState;
-import com.android.wm.shell.common.pip.PipDoubleTapHelper;
import org.junit.Assert;
import org.junit.Before;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipSnapAlgorithmTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipSnapAlgorithmTest.java
index ac13d7ffcd61..3e71ab3e1ad4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipSnapAlgorithmTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipSnapAlgorithmTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.pip;
+package com.android.wm.shell.common.pip;
import static org.junit.Assert.assertEquals;
@@ -25,8 +25,6 @@ import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
import com.android.wm.shell.ShellTestCase;
-import com.android.wm.shell.common.pip.PipBoundsState;
-import com.android.wm.shell.common.pip.PipSnapAlgorithm;
import org.junit.Before;
import org.junit.Test;
diff --git a/libs/hwui/aconfig/hwui_flags.aconfig b/libs/hwui/aconfig/hwui_flags.aconfig
index d3fc91b65829..7e1f2e2a3490 100644
--- a/libs/hwui/aconfig/hwui_flags.aconfig
+++ b/libs/hwui/aconfig/hwui_flags.aconfig
@@ -137,14 +137,6 @@ flag {
}
flag {
- name: "shader_color_space"
- is_exported: true
- namespace: "core_graphics"
- description: "API to set the working colorspace of a Shader or ColorFilter"
- bug: "299670828"
-}
-
-flag {
name: "query_global_priority"
namespace: "core_graphics"
description: "Attempt to query whether the vulkan driver supports the requested global priority before queue creation."
diff --git a/libs/hwui/jni/Shader.cpp b/libs/hwui/jni/Shader.cpp
index c02508977eba..eadb9dea566f 100644
--- a/libs/hwui/jni/Shader.cpp
+++ b/libs/hwui/jni/Shader.cpp
@@ -266,17 +266,11 @@ static jlong RuntimeShader_getNativeFinalizer(JNIEnv*, jobject) {
return static_cast<jlong>(reinterpret_cast<uintptr_t>(&SkRuntimeShaderBuilder_delete));
}
-static jlong RuntimeShader_create(JNIEnv* env, jobject, jlong shaderBuilder, jlong matrixPtr,
- jlong colorSpacePtr) {
+static jlong RuntimeShader_create(JNIEnv* env, jobject, jlong shaderBuilder, jlong matrixPtr) {
SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder);
const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
- auto colorSpace = GraphicsJNI::getNativeColorSpace(colorSpacePtr);
sk_sp<SkShader> shader = builder->makeShader(matrix);
ThrowIAE_IfNull(env, shader);
- if (colorSpace) {
- shader = shader->makeWithWorkingColorSpace(colorSpace);
- ThrowIAE_IfNull(env, shader);
- }
return reinterpret_cast<jlong>(shader.release());
}
@@ -385,7 +379,7 @@ static const JNINativeMethod gComposeShaderMethods[] = {
static const JNINativeMethod gRuntimeShaderMethods[] = {
{"nativeGetFinalizer", "()J", (void*)RuntimeShader_getNativeFinalizer},
- {"nativeCreateShader", "(JJJ)J", (void*)RuntimeShader_create},
+ {"nativeCreateShader", "(JJ)J", (void*)RuntimeShader_create},
{"nativeCreateBuilder", "(Ljava/lang/String;)J", (void*)RuntimeShader_createShaderBuilder},
{"nativeUpdateUniforms", "(JLjava/lang/String;[FZ)V",
(void*)RuntimeShader_updateFloatArrayUniforms},
diff --git a/ravenwood/runtime-jni/ravenwood_initializer.cpp b/ravenwood/runtime-jni/ravenwood_initializer.cpp
index 391c5d56b212..8a35ade649b2 100644
--- a/ravenwood/runtime-jni/ravenwood_initializer.cpp
+++ b/ravenwood/runtime-jni/ravenwood_initializer.cpp
@@ -26,6 +26,10 @@
#include <fcntl.h>
#include <set>
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <cstdlib>
#include "jni_helper.h"
@@ -182,17 +186,82 @@ static jboolean removeSystemProperty(JNIEnv* env, jclass, jstring javaKey) {
}
}
+// Find the PPID of child_pid using /proc/N/stat. The 4th field is the PPID.
+// Also returns child_pid's process name (2nd field).
+static pid_t getppid_of(pid_t child_pid, std::string& out_process_name) {
+ if (child_pid < 0) {
+ return -1;
+ }
+ std::string stat_file = "/proc/" + std::to_string(child_pid) + "/stat";
+ std::ifstream stat_stream(stat_file);
+ if (!stat_stream.is_open()) {
+ ALOGW("Unable to open '%s': %s", stat_file.c_str(), strerror(errno));
+ return -1;
+ }
+
+ std::string field;
+ int field_count = 0;
+ while (std::getline(stat_stream, field, ' ')) {
+ if (++field_count == 4) {
+ return atoi(field.c_str());
+ }
+ if (field_count == 2) {
+ out_process_name = field;
+ }
+ }
+ ALOGW("Unexpected format in '%s'", stat_file.c_str());
+ return -1;
+}
+
+// Find atest's PID. Climb up the process tree, and find "atest-py3".
+static pid_t find_atest_pid() {
+ auto ret = getpid(); // self (isolation runner process)
+
+ while (ret != -1) {
+ std::string proc;
+ ret = getppid_of(ret, proc);
+ if (proc == "(atest-py3)") {
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+// If $RAVENWOOD_LOG_OUT is set, redirect stdout/err to this file.
+// Originally it was added to allow to monitor log in realtime, with
+// RAVENWOOD_LOG_OUT=$(tty) atest...
+//
+// As a special case, if $RAVENWOOD_LOG_OUT is set to "-", we try to find
+// atest's process and send the output to its stdout. It's sort of hacky, but
+// this allows shell redirection to work on Ravenwood output too,
+// so e.g. `atest ... |tee atest.log` would work on Ravenwood's output.
+// (which wouldn't work with `RAVENWOOD_LOG_OUT=$(tty)`).
+//
+// Otherwise -- if $RAVENWOOD_LOG_OUT isn't set -- atest/tradefed just writes
+// the test's output to its own log file.
static void maybeRedirectLog() {
auto ravenwoodLogOut = getenv("RAVENWOOD_LOG_OUT");
- if (ravenwoodLogOut == NULL) {
+ if (ravenwoodLogOut == NULL || *ravenwoodLogOut == '\0') {
return;
}
- ALOGI("RAVENWOOD_LOG_OUT set. Redirecting output to %s", ravenwoodLogOut);
+ std::string path;
+ if (strcmp("-", ravenwoodLogOut) == 0) {
+ pid_t ppid = find_atest_pid();
+ if (ppid < 0) {
+ ALOGI("RAVENWOOD_LOG_OUT set to '-', but unable to find atest's PID");
+ return;
+ }
+ path = std::format("/proc/{}/fd/1", ppid);
+ } else {
+ path = ravenwoodLogOut;
+ }
+ ALOGI("RAVENWOOD_LOG_OUT set. Redirecting output to '%s'", path.c_str());
// Redirect stdin / stdout to /dev/tty.
- int ttyFd = open(ravenwoodLogOut, O_WRONLY | O_APPEND);
+ int ttyFd = open(path.c_str(), O_WRONLY | O_APPEND);
if (ttyFd == -1) {
- ALOGW("$RAVENWOOD_LOG_OUT is set to %s, but failed to open: %s ", ravenwoodLogOut,
+ ALOGW("$RAVENWOOD_LOG_OUT is set, but failed to open '%s': %s ", path.c_str(),
strerror(errno));
return;
}
diff --git a/services/core/java/com/android/server/am/AppStartInfoTracker.java b/services/core/java/com/android/server/am/AppStartInfoTracker.java
index 961022b7231b..517279bd7527 100644
--- a/services/core/java/com/android/server/am/AppStartInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppStartInfoTracker.java
@@ -54,15 +54,21 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.ProcessMap;
import com.android.internal.os.Clock;
import com.android.internal.os.MonotonicClock;
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
import com.android.server.IoThread;
import com.android.server.ServiceThread;
import com.android.server.SystemServiceManager;
import com.android.server.wm.WindowProcessController;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
@@ -1006,6 +1012,12 @@ public final class AppStartInfoTracker {
throws IOException, WireTypeMismatchException, ClassNotFoundException {
long token = proto.start(fieldId);
String pkgName = "";
+
+ // Create objects for reuse.
+ ByteArrayInputStream byteArrayInputStream = null;
+ ObjectInputStream objectInputStream = null;
+ TypedXmlPullParser typedXmlPullParser = null;
+
for (int next = proto.nextField();
next != ProtoInputStream.NO_MORE_FIELDS;
next = proto.nextField()) {
@@ -1017,7 +1029,7 @@ public final class AppStartInfoTracker {
AppStartInfoContainer container =
new AppStartInfoContainer(mAppStartInfoHistoryListSize);
int uid = container.readFromProto(proto, AppsStartInfoProto.Package.USERS,
- pkgName);
+ pkgName, byteArrayInputStream, objectInputStream, typedXmlPullParser);
// If the isolated process flag is enabled and the uid is that of an isolated
// process, then break early so that the container will not be added to mData.
@@ -1052,6 +1064,12 @@ public final class AppStartInfoTracker {
out = af.startWrite();
ProtoOutputStream proto = new ProtoOutputStream(out);
proto.write(AppsStartInfoProto.LAST_UPDATE_TIMESTAMP, now);
+
+ // Create objects for reuse.
+ ByteArrayOutputStream byteArrayOutputStream = null;
+ ObjectOutputStream objectOutputStream = null;
+ TypedXmlSerializer typedXmlSerializer = null;
+
synchronized (mLock) {
succeeded = forEachPackageLocked(
(packageName, records) -> {
@@ -1060,8 +1078,9 @@ public final class AppStartInfoTracker {
int uidArraySize = records.size();
for (int j = 0; j < uidArraySize; j++) {
try {
- records.valueAt(j)
- .writeToProto(proto, AppsStartInfoProto.Package.USERS);
+ records.valueAt(j).writeToProto(proto,
+ AppsStartInfoProto.Package.USERS, byteArrayOutputStream,
+ objectOutputStream, typedXmlSerializer);
} catch (IOException e) {
Slog.w(TAG, "Unable to write app start info into persistent"
+ "storage: " + e);
@@ -1414,19 +1433,23 @@ public final class AppStartInfoTracker {
}
@GuardedBy("mLock")
- void writeToProto(ProtoOutputStream proto, long fieldId) throws IOException {
+ void writeToProto(ProtoOutputStream proto, long fieldId,
+ ByteArrayOutputStream byteArrayOutputStream, ObjectOutputStream objectOutputStream,
+ TypedXmlSerializer typedXmlSerializer) throws IOException {
long token = proto.start(fieldId);
proto.write(AppsStartInfoProto.Package.User.UID, mUid);
int size = mInfos.size();
for (int i = 0; i < size; i++) {
- mInfos.get(i)
- .writeToProto(proto, AppsStartInfoProto.Package.User.APP_START_INFO);
+ mInfos.get(i).writeToProto(proto, AppsStartInfoProto.Package.User.APP_START_INFO,
+ byteArrayOutputStream, objectOutputStream, typedXmlSerializer);
}
proto.write(AppsStartInfoProto.Package.User.MONITORING_ENABLED, mMonitoringModeEnabled);
proto.end(token);
}
- int readFromProto(ProtoInputStream proto, long fieldId, String packageName)
+ int readFromProto(ProtoInputStream proto, long fieldId, String packageName,
+ ByteArrayInputStream byteArrayInputStream, ObjectInputStream objectInputStream,
+ TypedXmlPullParser typedXmlPullParser)
throws IOException, WireTypeMismatchException, ClassNotFoundException {
long token = proto.start(fieldId);
for (int next = proto.nextField();
@@ -1440,7 +1463,8 @@ public final class AppStartInfoTracker {
// Create record with monotonic time 0 in case the persisted record does not
// have a create time.
ApplicationStartInfo info = new ApplicationStartInfo(0);
- info.readFromProto(proto, AppsStartInfoProto.Package.User.APP_START_INFO);
+ info.readFromProto(proto, AppsStartInfoProto.Package.User.APP_START_INFO,
+ byteArrayInputStream, objectInputStream, typedXmlPullParser);
info.setPackageName(packageName);
mInfos.add(info);
break;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index a4f983c33eb9..b607b0fce9ab 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -2952,13 +2952,16 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
}
private boolean isOpaqueInner(@NonNull WindowContainer<?> container) {
- // If it's a leaf task fragment, then opacity is calculated based on its activities.
- if (container.asTaskFragment() != null
- && ((TaskFragment) container).isLeafTaskFragment()) {
+ final boolean isActivity = container.asActivityRecord() != null;
+ final boolean isLeafTaskFragment = container.asTaskFragment() != null
+ && ((TaskFragment) container).isLeafTaskFragment();
+ if (isActivity || isLeafTaskFragment) {
+ // When it is an activity or leaf task fragment, then opacity is calculated based
+ // on itself or its activities.
return container.getActivity(this,
true /* traverseTopToBottom */, null /* boundary */) != null;
}
- // When not a leaf, it's considered opaque if any of its opaque children fill this
+ // Otherwise, it's considered opaque if any of its opaque children fill this
// container, unless the children are adjacent fragments, in which case as long as they
// are all opaque then |container| is also considered opaque, even if the adjacent
// task fragment aren't filling.
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
index 3c74ad06a21f..a9be47d71213 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
@@ -509,6 +509,32 @@ public class ActivityTaskSupervisorTests extends WindowTestsBase {
assertThat(mSupervisor.mOpaqueContainerHelper.isOpaque(rootTask)).isTrue();
}
+ @Test
+ public void testOpaque_nonLeafTaskFragmentWithDirectActivity_opaque() {
+ final ActivityRecord directChildActivity = new ActivityBuilder(mAtm).setCreateTask(true)
+ .build();
+ directChildActivity.setOccludesParent(true);
+ final Task nonLeafTask = directChildActivity.getTask();
+ final TaskFragment directChildFragment = new TaskFragment(mAtm, new Binder(),
+ true /* createdByOrganizer */, false /* isEmbedded */);
+ nonLeafTask.addChild(directChildFragment, 0);
+
+ assertThat(mSupervisor.mOpaqueContainerHelper.isOpaque(nonLeafTask)).isTrue();
+ }
+
+ @Test
+ public void testOpaque_nonLeafTaskFragmentWithDirectActivity_transparent() {
+ final ActivityRecord directChildActivity = new ActivityBuilder(mAtm).setCreateTask(true)
+ .build();
+ directChildActivity.setOccludesParent(false);
+ final Task nonLeafTask = directChildActivity.getTask();
+ final TaskFragment directChildFragment = new TaskFragment(mAtm, new Binder(),
+ true /* createdByOrganizer */, false /* isEmbedded */);
+ nonLeafTask.addChild(directChildFragment, 0);
+
+ assertThat(mSupervisor.mOpaqueContainerHelper.isOpaque(nonLeafTask)).isFalse();
+ }
+
@NonNull
private TaskFragment createChildTaskFragment(@NonNull Task parent,
@WindowConfiguration.WindowingMode int windowingMode,