Merge "Visualizer: validate capture size" into main
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 5713e9e..a4b16f8 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -8158,6 +8158,10 @@
android:permission="android.permission.BIND_JOB_SERVICE">
</service>
+ <service android:name="com.android.system.virtualmachine.SecretkeeperJobService"
+ android:permission="android.permission.BIND_JOB_SERVICE">
+ </service>
+
<service android:name="com.android.server.PruneInstantAppsJobService"
android:permission="android.permission.BIND_JOB_SERVICE" >
</service>
diff --git a/graphics/java/android/graphics/text/MeasuredText.java b/graphics/java/android/graphics/text/MeasuredText.java
index 3f7f088..51100c0 100644
--- a/graphics/java/android/graphics/text/MeasuredText.java
+++ b/graphics/java/android/graphics/text/MeasuredText.java
@@ -29,11 +29,13 @@
import com.android.internal.util.Preconditions;
import dalvik.annotation.optimization.CriticalNative;
+import dalvik.annotation.optimization.NeverInline;
import libcore.util.NativeAllocationRegistry;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Locale;
import java.util.Objects;
/**
@@ -83,6 +85,30 @@
return mChars;
}
+ private void rangeCheck(int start, int end) {
+ if (start < 0 || start > end || end > mChars.length) {
+ throwRangeError(start, end);
+ }
+ }
+
+ @NeverInline
+ private void throwRangeError(int start, int end) {
+ throw new IllegalArgumentException(String.format(Locale.US,
+ "start(%d) end(%d) length(%d) out of bounds", start, end, mChars.length));
+ }
+
+ private void offsetCheck(int offset) {
+ if (offset < 0 || offset >= mChars.length) {
+ throwOffsetError(offset);
+ }
+ }
+
+ @NeverInline
+ private void throwOffsetError(int offset) {
+ throw new IllegalArgumentException(String.format(Locale.US,
+ "offset (%d) length(%d) out of bounds", offset, mChars.length));
+ }
+
/**
* Returns the width of a given range.
*
@@ -91,12 +117,7 @@
*/
public @FloatRange(from = 0.0) @Px float getWidth(
@IntRange(from = 0) int start, @IntRange(from = 0) int end) {
- Preconditions.checkArgument(0 <= start && start <= mChars.length,
- "start(%d) must be 0 <= start <= %d", start, mChars.length);
- Preconditions.checkArgument(0 <= end && end <= mChars.length,
- "end(%d) must be 0 <= end <= %d", end, mChars.length);
- Preconditions.checkArgument(start <= end,
- "start(%d) is larger than end(%d)", start, end);
+ rangeCheck(start, end);
return nGetWidth(mNativePtr, start, end);
}
@@ -118,12 +139,7 @@
*/
public void getBounds(@IntRange(from = 0) int start, @IntRange(from = 0) int end,
@NonNull Rect rect) {
- Preconditions.checkArgument(0 <= start && start <= mChars.length,
- "start(%d) must be 0 <= start <= %d", start, mChars.length);
- Preconditions.checkArgument(0 <= end && end <= mChars.length,
- "end(%d) must be 0 <= end <= %d", end, mChars.length);
- Preconditions.checkArgument(start <= end,
- "start(%d) is larger than end(%d)", start, end);
+ rangeCheck(start, end);
Preconditions.checkNotNull(rect);
nGetBounds(mNativePtr, mChars, start, end, rect);
}
@@ -137,12 +153,7 @@
*/
public void getFontMetricsInt(@IntRange(from = 0) int start, @IntRange(from = 0) int end,
@NonNull Paint.FontMetricsInt outMetrics) {
- Preconditions.checkArgument(0 <= start && start <= mChars.length,
- "start(%d) must be 0 <= start <= %d", start, mChars.length);
- Preconditions.checkArgument(0 <= end && end <= mChars.length,
- "end(%d) must be 0 <= end <= %d", end, mChars.length);
- Preconditions.checkArgument(start <= end,
- "start(%d) is larger than end(%d)", start, end);
+ rangeCheck(start, end);
Objects.requireNonNull(outMetrics);
long packed = nGetExtent(mNativePtr, mChars, start, end);
@@ -158,8 +169,7 @@
* @param offset an offset of the character.
*/
public @FloatRange(from = 0.0f) @Px float getCharWidthAt(@IntRange(from = 0) int offset) {
- Preconditions.checkArgument(0 <= offset && offset < mChars.length,
- "offset(%d) is larger than text length %d" + offset, mChars.length);
+ offsetCheck(offset);
return nGetCharWidthAt(mNativePtr, offset);
}
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index b6ba6a5..5320033 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -84,15 +84,6 @@
{
"name": "CtsVcnTestCases",
"file_patterns": ["VcnManagementService\\.java"]
- },
- {
- "name": "FrameworksNetTests",
- "options": [
- {
- "exclude-annotation": "com.android.testutils.SkipPresubmit"
- }
- ],
- "file_patterns": ["VpnManagerService\\.java"]
}
],
"presubmit-large": [
@@ -126,5 +117,10 @@
],
"file_patterns": ["VpnManagerService\\.java"]
}
+ ],
+ "postsubmit": [
+ {
+ "name": "FrameworksVpnTests"
+ }
]
}
diff --git a/services/core/java/com/android/server/connectivity/TEST_MAPPING b/services/core/java/com/android/server/connectivity/TEST_MAPPING
index 687d4b0..c2b1c77 100644
--- a/services/core/java/com/android/server/connectivity/TEST_MAPPING
+++ b/services/core/java/com/android/server/connectivity/TEST_MAPPING
@@ -7,7 +7,7 @@
"exclude-annotation": "com.android.testutils.SkipPresubmit"
}
],
- "file_patterns": ["Vpn\\.java", "VpnIkeV2Utils\\.java", "VpnProfileStore\\.java"]
+ "file_patterns": ["VpnIkeV2Utils\\.java", "VpnProfileStore\\.java"]
}
],
"presubmit-large": [
@@ -26,5 +26,10 @@
],
"file_patterns": ["Vpn\\.java", "VpnIkeV2Utils\\.java", "VpnProfileStore\\.java"]
}
+ ],
+ "postsubmit":[
+ {
+ "name":"FrameworksVpnTests"
+ }
]
}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 44c4b57..2adbaaa 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1251,7 +1251,7 @@
if (isUidStateChangeRelevant(callbackInfo, procState, procStateSeq, capability)) {
callbackInfo.update(uid, procState, procStateSeq, capability);
if (!callbackInfo.isPending) {
- mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED, callbackInfo)
+ mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED, uid, 0)
.sendToTarget();
callbackInfo.isPending = true;
}
@@ -1263,7 +1263,6 @@
synchronized (mUidStateCallbackInfos) {
mUidStateCallbackInfos.remove(uid);
}
- // TODO: b/327058756 - Remove any pending UID_MSG_STATE_CHANGED on the handler.
mUidEventHandler.obtainMessage(UID_MSG_GONE, uid, 0).sendToTarget();
}
};
@@ -5851,13 +5850,13 @@
private final Handler.Callback mUidEventHandlerCallback = new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
+ final int uid = msg.arg1;
switch (msg.what) {
case UID_MSG_STATE_CHANGED: {
- handleUidChanged((UidStateCallbackInfo) msg.obj);
+ handleUidChanged(uid);
return true;
}
case UID_MSG_GONE: {
- final int uid = msg.arg1;
handleUidGone(uid);
return true;
}
@@ -5868,23 +5867,27 @@
}
};
- void handleUidChanged(@NonNull UidStateCallbackInfo uidStateCallbackInfo) {
+ void handleUidChanged(int uid) {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged");
try {
- boolean updated;
- final int uid;
final int procState;
final long procStateSeq;
final int capability;
- synchronized (mUidRulesFirstLock) {
- synchronized (mUidStateCallbackInfos) {
- uid = uidStateCallbackInfo.uid;
- procState = uidStateCallbackInfo.procState;
- procStateSeq = uidStateCallbackInfo.procStateSeq;
- capability = uidStateCallbackInfo.capability;
- uidStateCallbackInfo.isPending = false;
+ synchronized (mUidStateCallbackInfos) {
+ final UidStateCallbackInfo uidStateCallbackInfo = mUidStateCallbackInfos.get(uid);
+ if (uidStateCallbackInfo == null) {
+ // This can happen if UidObserver#onUidGone gets called before we reach
+ // here. In this case, there is no point in processing this change as this
+ // will immediately be followed by a call to handleUidGone anyway.
+ return;
}
-
+ procState = uidStateCallbackInfo.procState;
+ procStateSeq = uidStateCallbackInfo.procStateSeq;
+ capability = uidStateCallbackInfo.capability;
+ uidStateCallbackInfo.isPending = false;
+ }
+ final boolean updated;
+ synchronized (mUidRulesFirstLock) {
// We received a uid state change callback, add it to the history so that it
// will be useful for debugging.
mLogger.uidStateChanged(uid, procState, procStateSeq, capability);
@@ -5907,6 +5910,14 @@
void handleUidGone(int uid) {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidGone");
try {
+ synchronized (mUidStateCallbackInfos) {
+ if (mUidStateCallbackInfos.contains(uid)) {
+ // This can happen if UidObserver#onUidStateChanged gets called before we
+ // reach here. In this case, there is no point in processing this change as this
+ // will immediately be followed by a call to handleUidChanged anyway.
+ return;
+ }
+ }
final boolean updated;
synchronized (mUidRulesFirstLock) {
updated = removeUidStateUL(uid);
diff --git a/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp b/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp
new file mode 100644
index 0000000..e94b8ad
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp
@@ -0,0 +1,56 @@
+// Copyright (C) 2024 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.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_test {
+ name: "RollbackPackageHealthObserverTests",
+
+ srcs: [
+ "*.java",
+ ],
+
+ static_libs: [
+ "androidx.test.runner",
+ "mockito-target-extended-minus-junit4",
+ "services.core",
+ "truth",
+ "flag-junit",
+ ],
+
+ libs: [
+ "android.test.mock",
+ "android.test.base",
+ "android.test.runner",
+ ],
+
+ jni_libs: [
+ "libdexmakerjvmtiagent",
+ "libstaticjvmtiagent",
+ ],
+
+ certificate: "platform",
+ platform_apis: true,
+ test_suites: [
+ "device-tests",
+ "automotive-tests",
+ ],
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/rollback/AndroidManifest.xml b/services/tests/mockingservicestests/src/com/android/server/rollback/AndroidManifest.xml
new file mode 100644
index 0000000..c52dbde
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/rollback/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 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.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.server.rollback">
+
+ <uses-sdk android:targetSdkVersion="35" />
+
+ <application android:testOnly="true"
+ android:debuggable="true">
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.server.rollback"
+ android:label="Frameworks Rollback Package Health Observer test" />
+</manifest>
diff --git a/services/tests/mockingservicestests/src/com/android/server/rollback/AndroidTest.xml b/services/tests/mockingservicestests/src/com/android/server/rollback/AndroidTest.xml
new file mode 100644
index 0000000..635183c
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/rollback/AndroidTest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 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.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<configuration description="Runs Rollback Package Health Observer Tests.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-instrumentation" />
+
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="install-arg" value="-t" />
+ <option name="test-file-name" value="RollbackPackageHealthObserverTests.apk" />
+ </target_preparer>
+
+ <option name="test-tag" value="RollbackPackageHealthObserverTests" />
+
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="com.android.server.rollback" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+ <option name="hidden-api-checks" value="false"/>
+ </test>
+</configuration>
diff --git a/services/tests/mockingservicestests/src/com/android/server/rollback/TEST_MAPPING b/services/tests/mockingservicestests/src/com/android/server/rollback/TEST_MAPPING
index e42bdad..6ac56bf 100644
--- a/services/tests/mockingservicestests/src/com/android/server/rollback/TEST_MAPPING
+++ b/services/tests/mockingservicestests/src/com/android/server/rollback/TEST_MAPPING
@@ -1,7 +1,7 @@
{
"postsubmit": [
{
- "name": "FrameworksMockingServicesTests",
+ "name": "RollbackPackageHealthObserverTests",
"options": [
{
"include-filter": "com.android.server.rollback"
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index 15cd511..a5f7963 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -2404,6 +2404,45 @@
}
@Test
+ public void testObsoleteHandleUidGone() throws Exception {
+ callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_TOP, 51);
+ assertFalse(mService.isUidNetworkingBlocked(UID_A, false));
+
+ clearInvocations(mNetworkManager);
+
+ // In the service, handleUidGone is only called from mUidEventHandler. Then a call to it may
+ // be rendered obsolete by a newer uid change posted on the handler. The latest uid state
+ // change is always reflected in the current UidStateChangeCallbackInfo for the uid, so to
+ // simulate an obsolete call for test, we directly call handleUidGone and leave the state in
+ // UidStateChangeCallbackInfo set by the previous call to onUidStateChanged(TOP). This call
+ // should then do nothing.
+ mService.handleUidGone(UID_A);
+
+ verify(mNetworkManager, times(0)).setFirewallUidRule(anyInt(), anyInt(), anyInt());
+ assertFalse(mService.isUidNetworkingBlocked(UID_A, false));
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
+ public void testObsoleteHandleUidChanged() throws Exception {
+ callAndWaitOnUidGone(UID_A);
+ assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
+
+ clearInvocations(mNetworkManager);
+
+ // In the service, handleUidChanged is only called from mUidEventHandler. Then a call to it
+ // may be rendered obsolete by an immediate uid-gone posted on the handler. The latest uid
+ // state change is always reflected in the current UidStateChangeCallbackInfo for the uid,
+ // so to simulate an obsolete call for test, we directly call handleUidChanged and leave the
+ // state in UidStateChangeCallbackInfo as null as it would get removed by the previous call
+ // to onUidGone(). This call should then do nothing.
+ mService.handleUidChanged(UID_A);
+
+ verify(mNetworkManager, times(0)).setFirewallUidRule(anyInt(), anyInt(), anyInt());
+ assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
+ }
+
+ @Test
public void testLowPowerStandbyAllowlist() throws Exception {
// Chain background is also enabled but these procstates are important enough to be exempt.
callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_TOP, 0);