diff options
10 files changed, 233 insertions, 46 deletions
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 5713e9ee1a80..a4b16f8b4025 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 3f7f0880d160..51100c03aabd 100644 --- a/graphics/java/android/graphics/text/MeasuredText.java +++ b/graphics/java/android/graphics/text/MeasuredText.java @@ -29,11 +29,13 @@ import android.util.Log; 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 @@ public class MeasuredText { 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 class MeasuredText { */ 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 class MeasuredText { */ 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 class MeasuredText { */ 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 @@ public class MeasuredText { * @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 b6ba6a5fc5c4..5320033c9fc0 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 687d4b06b4c0..c2b1c77e7a10 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 44c4b57a52c9..2adbaaa1348c 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } }; - 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 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 000000000000..e94b8ad0a9ac --- /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 000000000000..c52dbdee4b4b --- /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 000000000000..635183c553bf --- /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 e42bdad97730..6ac56bfc254a 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 15cd5115a49e..a5f7963b9c96 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 @@ public class NetworkPolicyManagerServiceTest { } @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); |