diff options
23 files changed, 273 insertions, 142 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index 9fc4fff6f297..960bb5c3f276 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -279,6 +279,7 @@ cc_aconfig_library { name: "android_nfc_flags_aconfig_c_lib", vendor_available: true, aconfig_declarations: "android.nfc.flags-aconfig", + min_sdk_version: "34", apex_available: [ "//apex_available:platform", "com.android.nfcservices", @@ -575,6 +576,8 @@ java_aconfig_library { min_sdk_version: "30", apex_available: [ "//apex_available:platform", + "com.android.art", + "com.android.art.debug", "com.android.permission", ], } diff --git a/Android.bp b/Android.bp index 66a0077883cf..20e58ed377a8 100644 --- a/Android.bp +++ b/Android.bp @@ -368,6 +368,7 @@ java_defaults { "view-inspector-annotation-processor", "staledataclass-annotation-processor", "error_prone_android_framework", + "systemfeatures-metadata-processor", ], // Exports needed for staledataclass-annotation-processor, see b/139342589. javacflags: [ diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 5e69ec186bdb..fb7030fe0ccf 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -6859,21 +6859,44 @@ public final class ActivityThread extends ClientTransactionHandler final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) { if (start) { - try { - switch (profileType) { - default: + switch (profileType) { + case ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD: + if (!com.android.art.flags.Flags.alwaysEnableProfileCode()) { + Slog.w(TAG, "Low overhead tracing feature is not enabled"); + break; + } + VMDebug.startLowOverheadTrace(); + break; + default: + try { mProfiler.setProfiler(profilerInfo); mProfiler.startProfiling(); break; - } - } catch (RuntimeException e) { - Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile - + " -- can the process access this path?"); - } finally { - profilerInfo.closeFd(); + } catch (RuntimeException e) { + Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile + + " -- can the process access this path?"); + } finally { + profilerInfo.closeFd(); + } } } else { switch (profileType) { + case ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD: + if (!com.android.art.flags.Flags.alwaysEnableProfileCode()) { + if (profilerInfo != null) { + profilerInfo.closeFd(); + } + Slog.w(TAG, "Low overhead tracing feature is not enabled"); + break; + } + if (profilerInfo != null) { + FileDescriptor fd = profilerInfo.profileFd.getFileDescriptor(); + VMDebug.TraceDestination dst = + VMDebug.TraceDestination.fromFileDescriptor(fd); + VMDebug.dumpLowOverheadTrace(dst); + } + VMDebug.stopLowOverheadTrace(); + break; default: mProfiler.stopProfiling(); break; diff --git a/core/java/android/app/ProfilerInfo.java b/core/java/android/app/ProfilerInfo.java index bcae22a38f9e..0348b6de9964 100644 --- a/core/java/android/app/ProfilerInfo.java +++ b/core/java/android/app/ProfilerInfo.java @@ -32,6 +32,12 @@ import java.util.Objects; * {@hide} */ public class ProfilerInfo implements Parcelable { + // Regular profiling which provides different modes of profiling at some performance cost. + public static final int PROFILE_TYPE_REGULAR = 0; + + // Low overhead profiling that captures a simple sliding window of past events. + public static final int PROFILE_TYPE_LOW_OVERHEAD = 1; + // Version of the profiler output public static final int OUTPUT_VERSION_DEFAULT = 1; // CLOCK_TYPE_DEFAULT chooses the default used by ART. ART uses CLOCK_TYPE_DUAL by default (see diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 3971e98442bc..759d1919e4e1 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -3116,6 +3116,16 @@ public abstract class PackageManager { public static final long MAXIMUM_VERIFICATION_TIMEOUT = 60*60*1000; /** + * As the generated feature count is useful for classes that may not be compiled in the same + * annotation processing unit as PackageManager, we redeclare it here for visibility. + * + * @hide + */ + @VisibleForTesting + public static final int SDK_FEATURE_COUNT = + com.android.internal.pm.SystemFeaturesMetadata.SDK_FEATURE_COUNT; + + /** * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device's * audio pipeline is low-latency, more suitable for audio applications sensitive to delays or * lag in sound input or output. diff --git a/core/java/android/net/LocalSocket.java b/core/java/android/net/LocalSocket.java index a86396cd7c8d..0fedf8ecbb23 100644 --- a/core/java/android/net/LocalSocket.java +++ b/core/java/android/net/LocalSocket.java @@ -65,7 +65,7 @@ public class LocalSocket implements Closeable { } /** - * Creates a AF_LOCAL/UNIX domain stream socket with given socket type + * Creates a AF_LOCAL/UNIX domain socket with the given socket type. * * @param sockType either {@link #SOCKET_DGRAM}, {@link #SOCKET_STREAM} * or {@link #SOCKET_SEQPACKET} diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig index 5d1d7583d8f8..392b42d2d354 100644 --- a/core/java/android/security/flags.aconfig +++ b/core/java/android/security/flags.aconfig @@ -105,6 +105,7 @@ flag { namespace: "biometrics" description: "Clear StrongAuth on add credential" bug: "320817991" + is_exported: true } flag { @@ -127,4 +128,5 @@ flag { namespace: "hardware_backed_security" description: "Feature flag for exposing KeyStore grant APIs" bug: "351158708" + is_exported: true } diff --git a/core/java/android/service/voice/OWNERS b/core/java/android/service/voice/OWNERS index 5f9f6bde3129..b6f0270dfbbc 100644 --- a/core/java/android/service/voice/OWNERS +++ b/core/java/android/service/voice/OWNERS @@ -1,6 +1,6 @@ # Bug component: 533220 - include /core/java/android/app/assist/OWNERS +atneya@google.com # The owner here should not be assist owner adudani@google.com diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTest.java b/core/tests/coretests/src/android/content/pm/PackageManagerTest.java index 20421d105db8..d080ee728e02 100644 --- a/core/tests/coretests/src/android/content/pm/PackageManagerTest.java +++ b/core/tests/coretests/src/android/content/pm/PackageManagerTest.java @@ -24,6 +24,9 @@ import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +import java.lang.reflect.Modifier; +import java.util.Arrays; + @RunWith(AndroidJUnit4.class) @SmallTest public class PackageManagerTest { @@ -46,4 +49,25 @@ public class PackageManagerTest { public void testResolveInfoFlags() throws Exception { assertThat(PackageManager.ResolveInfoFlags.of(42L).getValue()).isEqualTo(42L); } + + @Test + public void testSdkFeatureCount() throws Exception { + // Check to make sure the system feature `SdkConst` annotation processor yields sensible + // results. We don't care about the exactness, just that it's not pathologically wrong. + assertThat(PackageManager.SDK_FEATURE_COUNT).isGreaterThan(150); + assertThat(PackageManager.SDK_FEATURE_COUNT).isLessThan(500); + assertThat(PackageManager.SDK_FEATURE_COUNT) + .isWithin(50) + .of(getApproximateFeatureCountUsingReflection()); + } + + /* Return a ballpark estimate of the feature count using FEATURE_ field names. */ + private static int getApproximateFeatureCountUsingReflection() { + return (int) + Arrays.stream(PackageManager.class.getFields()) + .filter(field -> Modifier.isStatic(field.getModifiers())) + .filter(field -> Modifier.isFinal(field.getModifiers())) + .filter(field -> field.getName().startsWith("FEATURE_")) + .count(); + } } diff --git a/core/tests/coretests/src/android/os/PowerManagerTest.java b/core/tests/coretests/src/android/os/PowerManagerTest.java index b9a12ad57c33..9758cdd75f0b 100644 --- a/core/tests/coretests/src/android/os/PowerManagerTest.java +++ b/core/tests/coretests/src/android/os/PowerManagerTest.java @@ -28,11 +28,10 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; -import android.platform.test.flag.junit.RavenwoodFlagsValueProvider; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.InstrumentationRegistry; @@ -52,7 +51,7 @@ import java.util.concurrent.Executor; import java.util.concurrent.Executors; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = PowerManager.class) +@DisabledOnRavenwood(blockedBy = PowerManager.class) public class PowerManagerTest { private static final String TAG = "PowerManagerTest"; @@ -77,19 +76,14 @@ public class PowerManagerTest { String[] keys, String[] values); static { - if (!RavenwoodRule.isUnderRavenwood()) { + if (!RavenwoodRule.isOnRavenwood()) { System.loadLibrary("powermanagertest_jni"); } } - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule(); - // Required for RequiresFlagsEnabled and RequiresFlagsDisabled annotations to take effect. @Rule - public final CheckFlagsRule mCheckFlagsRule = RavenwoodRule.isOnRavenwood() - ? RavenwoodFlagsValueProvider.createAllOnCheckFlagsRule() - : DeviceFlagsValueProvider.createCheckFlagsRule(); + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); /** * Setup any common data for the upcoming tests. diff --git a/core/tests/coretests/src/android/os/WorkDurationUnitTest.java b/core/tests/coretests/src/android/os/WorkDurationUnitTest.java index fcdc5905ef88..c6474c96e965 100644 --- a/core/tests/coretests/src/android/os/WorkDurationUnitTest.java +++ b/core/tests/coretests/src/android/os/WorkDurationUnitTest.java @@ -18,12 +18,10 @@ package android.os; import static org.junit.Assert.assertThrows; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; -import android.platform.test.flag.junit.RavenwoodFlagsValueProvider; -import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.runner.AndroidJUnit4; @@ -34,16 +32,11 @@ import org.junit.runner.RunWith; import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = WorkDuration.class) +@DisabledOnRavenwood(blockedBy = WorkDuration.class) public class WorkDurationUnitTest { - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule(); - // Required for RequiresFlagsEnabled and RequiresFlagsDisabled annotations to take effect. @Rule - public final CheckFlagsRule mCheckFlagsRule = RavenwoodRule.isOnRavenwood() - ? RavenwoodFlagsValueProvider.createAllOnCheckFlagsRule() - : DeviceFlagsValueProvider.createCheckFlagsRule(); + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); @Before public void setUp() { diff --git a/omapi/aidl/Android.bp b/omapi/aidl/Android.bp index e71597a27a39..3916bf3df73d 100644 --- a/omapi/aidl/Android.bp +++ b/omapi/aidl/Android.bp @@ -24,6 +24,7 @@ aidl_interface { backend: { java: { sdk_version: "module_current", + min_sdk_version: "35", // Make it 36 once available. apex_available: [ "//apex_available:platform", "com.android.nfcservices", diff --git a/packages/Vcn/framework-b/Android.bp b/packages/Vcn/framework-b/Android.bp index be64bb1ae404..8b010c7f2ee7 100644 --- a/packages/Vcn/framework-b/Android.bp +++ b/packages/Vcn/framework-b/Android.bp @@ -40,5 +40,28 @@ java_sdk_library { "android.net.vcn", ], + impl_library_visibility: [ + // Using for test only + "//cts/tests/netlegacy22.api", + "//cts/tests/tests/vcn", + "//external/sl4a:__subpackages__", + "//frameworks/base/core/tests/bandwidthtests", + "//frameworks/base/core/tests/benchmarks", + "//frameworks/base/core/tests/utillib", + "//frameworks/base/services/tests/VpnTests", + "//frameworks/base/tests/vcn", + "//frameworks/opt/telephony/tests/telephonytests", + "//packages/modules/CaptivePortalLogin/tests", + "//packages/modules/Connectivity/staticlibs/testutils", + "//packages/modules/Connectivity/staticlibs/tests:__subpackages__", + "//packages/modules/Connectivity/Tethering/tests:__subpackages__", + "//packages/modules/Connectivity/tests:__subpackages__", + "//packages/modules/Connectivity/thread/tests:__subpackages__", + "//packages/modules/IPsec/tests/iketests", + "//packages/modules/NetworkStack", + "//packages/modules/NetworkStack/tests:__subpackages__", + "//packages/modules/Wifi/service/tests/wifitests", + ], + // TODO: b/375213246 Expose this library to Tethering module } diff --git a/ravenwood/test-authors.md b/ravenwood/test-authors.md index c29fb7f67e78..6d82a744bc4f 100644 --- a/ravenwood/test-authors.md +++ b/ravenwood/test-authors.md @@ -106,45 +106,6 @@ You can also run your new tests automatically via `TEST_MAPPING` rules like this > **Note:** There's a known bug #308854804 where `TEST_MAPPING` is not being applied, so we're currently planning to run all Ravenwood tests unconditionally in presubmit for changes to `frameworks/base/` and `cts/` until there is a better path forward. -## Strategies for feature flags - -Ravenwood supports writing tests against logic that uses feature flags through the existing `SetFlagsRule` infrastructure maintained by the feature flagging team: - -``` -import android.platform.test.flag.junit.SetFlagsRule; - -@RunWith(AndroidJUnit4.class) -public class MyCodeTest { - @Rule - public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(SetFlagsRule.DefaultInitValueType.NULL_DEFAULT); - - @Test - public void testEnabled() { - mSetFlagsRule.enableFlags(Flags.FLAG_MY_FLAG); - // verify test logic that depends on flag being enabled - } -``` - -This naturally composes together well with any `RavenwoodRule` that your test may need. - -While `SetFlagsRule` is generally a best-practice (as it can explicitly confirm behaviors for both "on" and "off" states), you may need to write tests that use `CheckFlagsRule` (such as when writing CTS). Ravenwood currently supports `CheckFlagsRule` by offering "all-on" and "all-off" behaviors: - -``` -import android.platform.test.flag.junit.CheckFlagsRule; -import android.platform.test.flag.junit.DeviceFlagsValueProvider; -import android.platform.test.flag.junit.RavenwoodFlagsValueProvider; -import android.platform.test.ravenwood.RavenwoodRule; - -@RunWith(AndroidJUnit4.class) -public class MyCodeTest { - @Rule - public final CheckFlagsRule mCheckFlagsRule = RavenwoodRule.isUnderRavenwood() - ? RavenwoodFlagsValueProvider.createAllOnCheckFlagsRule() - : DeviceFlagsValueProvider.createCheckFlagsRule(); -``` - -Ravenwood currently doesn't have knowledge of the "default" value of any flags, so using `createAllOnCheckFlagsRule()` is recommended to verify the widest possible set of behaviors. The example code above falls back to using default values from `DeviceFlagsValueProvider` when not running on Ravenwood. - ## Strategies for migration/bivalent tests Ravenwood aims to support tests that are written in a “bivalent” way, where the same test code can be dual-compiled to run on both a real Android device and under a Ravenwood environment. diff --git a/services/core/Android.bp b/services/core/Android.bp index f08c876e3104..349f3ee2b9f0 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -233,7 +233,6 @@ java_library_static { "core_os_flags_lib", "connectivity_flags_lib", "dreams_flags_lib", - "aconfig_flags_java", "aconfig_new_storage_flags_lib", "powerstats_flags_lib", "locksettings_flags_lib", diff --git a/services/core/java/com/android/server/SecurityStateManagerService.java b/services/core/java/com/android/server/SecurityStateManagerService.java index 98039be20897..fe21fbda7130 100644 --- a/services/core/java/com/android/server/SecurityStateManagerService.java +++ b/services/core/java/com/android/server/SecurityStateManagerService.java @@ -22,6 +22,7 @@ import static android.os.SecurityStateManager.KEY_VENDOR_SPL; import android.content.Context; import android.content.pm.PackageManager; +import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.ISecurityStateManager; @@ -56,6 +57,15 @@ public class SecurityStateManagerService extends ISecurityStateManager.Stub { @Override public Bundle getGlobalSecurityState() { + final long token = Binder.clearCallingIdentity(); + try { + return getGlobalSecurityStateInternal(); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + private Bundle getGlobalSecurityStateInternal() { Bundle globalSecurityState = new Bundle(); globalSecurityState.putString(KEY_SYSTEM_SPL, Build.VERSION.SECURITY_PATCH); globalSecurityState.putString(KEY_VENDOR_SPL, diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 4a4a1b4de0f0..0152f94072f4 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -7609,7 +7609,7 @@ public class ActivityManagerService extends IActivityManager.Stub } void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo, - ApplicationInfo sdkSandboxClientApp) { + ApplicationInfo sdkSandboxClientApp, int profileType) { synchronized (mAppProfiler.mProfilerLock) { if (!Build.IS_DEBUGGABLE) { boolean isAppDebuggable = (app.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; @@ -7625,7 +7625,7 @@ public class ActivityManagerService extends IActivityManager.Stub + "and not profileable by shell: " + app.packageName); } } - mAppProfiler.setProfileAppLPf(processName, profilerInfo); + mAppProfiler.setProfileAppLPf(processName, profilerInfo, profileType); } } @@ -17883,7 +17883,8 @@ public class ActivityManagerService extends IActivityManager.Stub + android.Manifest.permission.SET_ACTIVITY_WATCHER); } - if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { + if (start && profileType == ProfilerInfo.PROFILE_TYPE_REGULAR + && (profilerInfo == null || profilerInfo.profileFd == null)) { throw new IllegalArgumentException("null profile info or fd"); } @@ -19499,7 +19500,9 @@ public class ActivityManagerService extends IActivityManager.Stub } if (profilerInfo != null) { - setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo, null); + // We only support normal method tracing along with app startup for now. + setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo, + null, /*profileType= */ ProfilerInfo.PROFILE_TYPE_REGULAR); } wmLock.notify(); } diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 955437b23de4..18539739642c 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -1081,7 +1081,7 @@ final class ActivityManagerShellCommand extends ShellCommand { String profileFile = null; boolean start = false; int userId = UserHandle.USER_CURRENT; - int profileType = 0; + int profileType = ProfilerInfo.PROFILE_TYPE_REGULAR; mSamplingInterval = 0; mStreaming = false; mClockType = ProfilerInfo.CLOCK_TYPE_DEFAULT; @@ -1123,6 +1123,18 @@ final class ActivityManagerShellCommand extends ShellCommand { } } process = getNextArgRequired(); + } else if ("lowoverhead".equals(cmd)) { + // This is an experimental low overhead profiling. + profileType = ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD; + cmd = getNextArgRequired(); + if ("start".equals(cmd)) { + start = true; + } else if ("stop".equals(cmd)) { + start = false; + } else { + throw new IllegalArgumentException("Profile command not valid"); + } + process = getNextArgRequired(); } else { // Compatibility with old syntax: process is specified first. process = cmd; @@ -1142,7 +1154,12 @@ final class ActivityManagerShellCommand extends ShellCommand { ParcelFileDescriptor fd = null; ProfilerInfo profilerInfo = null; - if (start) { + // For regular method tracing profileFile should be provided with the start command. For + // low overhead method tracing the profileFile is optional and provided with the stop + // command. + if ((start && profileType == ProfilerInfo.PROFILE_TYPE_REGULAR) + || (profileType == ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD + && !start && getRemainingArgsCount() > 0)) { profileFile = getNextArgRequired(); fd = openFileForSystem(profileFile, "w"); if (fd == null) { diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java index dda48adbf732..79a0d737bf6c 100644 --- a/services/core/java/com/android/server/am/AppProfiler.java +++ b/services/core/java/com/android/server/am/AppProfiler.java @@ -1990,7 +1990,7 @@ public class AppProfiler { } @GuardedBy("mProfilerLock") - private void stopProfilerLPf(ProcessRecord proc, int profileType) { + private void stopProfilerLPf(ProcessRecord proc, ProfilerInfo profilerInfo, int profileType) { if (proc == null || proc == mProfileData.getProfileProc()) { proc = mProfileData.getProfileProc(); profileType = mProfileType; @@ -2004,7 +2004,7 @@ public class AppProfiler { return; } try { - thread.profilerControl(false, null, profileType); + thread.profilerControl(false, profilerInfo, profileType); } catch (RemoteException e) { throw new IllegalStateException("Process disappeared"); } @@ -2039,41 +2039,58 @@ public class AppProfiler { ProfilerInfo profilerInfo, int profileType) { try { if (start) { - stopProfilerLPf(null, 0); + boolean needsFile = (profileType == ProfilerInfo.PROFILE_TYPE_REGULAR); + stopProfilerLPf(null, null, 0); mService.setProfileApp(proc.info, proc.processName, profilerInfo, - proc.isSdkSandbox ? proc.getClientInfoForSdkSandbox() : null); + proc.isSdkSandbox ? proc.getClientInfoForSdkSandbox() : null, profileType); mProfileData.setProfileProc(proc); mProfileType = profileType; - ParcelFileDescriptor fd = profilerInfo.profileFd; - try { - fd = fd.dup(); - } catch (IOException e) { - fd = null; + + ParcelFileDescriptor fd = null; + if (needsFile) { + fd = profilerInfo.profileFd; + try { + fd = fd.dup(); + } catch (IOException e) { + fd = null; + } + profilerInfo.profileFd = fd; } - profilerInfo.profileFd = fd; + proc.mProfile.getThread().profilerControl(start, profilerInfo, profileType); - fd = null; - try { - mProfileData.getProfilerInfo().profileFd.close(); - } catch (IOException e) { - } - mProfileData.getProfilerInfo().profileFd = null; - - if (proc.getPid() == mService.MY_PID) { - // When profiling the system server itself, avoid closing the file - // descriptor, as profilerControl will not create a copy. - // Note: it is also not correct to just set profileFd to null, as the - // whole ProfilerInfo instance is passed down! - profilerInfo = null; + + if (needsFile) { + fd = null; + try { + mProfileData.getProfilerInfo().profileFd.close(); + } catch (IOException e) { + } + mProfileData.getProfilerInfo().profileFd = null; + + if (proc.getPid() == mService.MY_PID) { + // When profiling the system server itself, avoid closing the file + // descriptor, as profilerControl will not create a copy. + // Note: it is also not correct to just set profileFd to null, as the + // whole ProfilerInfo instance is passed down! + profilerInfo = null; + } } } else { - stopProfilerLPf(proc, profileType); + boolean mayNeedFile = (profileType == ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD); if (profilerInfo != null && profilerInfo.profileFd != null) { + ParcelFileDescriptor fd = profilerInfo.profileFd; try { - profilerInfo.profileFd.close(); + if (mayNeedFile) { + fd = fd.dup(); + } else { + fd.close(); + } } catch (IOException e) { + fd = null; } + profilerInfo.profileFd = fd; } + stopProfilerLPf(proc, profilerInfo, profileType); } return true; @@ -2090,7 +2107,7 @@ public class AppProfiler { } @GuardedBy("mProfilerLock") - void setProfileAppLPf(String processName, ProfilerInfo profilerInfo) { + void setProfileAppLPf(String processName, ProfilerInfo profilerInfo, int profileType) { mProfileData.setProfileApp(processName); if (mProfileData.getProfilerInfo() != null) { @@ -2101,8 +2118,10 @@ public class AppProfiler { } } } - mProfileData.setProfilerInfo(new ProfilerInfo(profilerInfo)); - mProfileType = 0; + if (profilerInfo != null) { + mProfileData.setProfilerInfo(new ProfilerInfo(profilerInfo)); + } + mProfileType = profileType; } @GuardedBy("mProfilerLock") diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java index 90f92b079220..f79256d6147b 100644 --- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java +++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java @@ -39,7 +39,6 @@ import android.aconfigd.Aconfigd.StorageRequestMessages; import android.aconfigd.Aconfigd.StorageReturnMessage; import android.aconfigd.Aconfigd.StorageReturnMessages; import static com.android.aconfig_new_storage.Flags.enableAconfigStorageDaemon; -import static com.android.aconfig.flags.Flags.enableSystemAconfigdRust; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -392,8 +391,7 @@ public class SettingsToPropertiesMapper { static ProtoInputStream sendAconfigdRequests(ProtoOutputStream requests) { // connect to aconfigd socket LocalSocket client = new LocalSocket(); - String socketName = enableSystemAconfigdRust() - ? "aconfigd_system" : "aconfigd"; + String socketName = "aconfigd_system"; try { client.connect(new LocalSocketAddress( socketName, LocalSocketAddress.Namespace.RESERVED)); diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 47a79a3c4051..ca831d1c7ee8 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -61,6 +61,7 @@ import static com.android.server.pm.PackageManagerShellCommandDataLoader.Metadat import android.Manifest; import android.annotation.AnyThread; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -186,6 +187,7 @@ import com.android.internal.util.Preconditions; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; import com.android.server.LocalServices; +import com.android.server.art.ArtManagedInstallFileHelper; import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.dex.DexManager; import com.android.server.pm.pkg.AndroidPackage; @@ -848,7 +850,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { if (file.getName().endsWith(REMOVE_MARKER_EXTENSION)) return false; if (file.getName().endsWith(V4Signature.EXT)) return false; if (isAppMetadata(file)) return false; - if (DexMetadataHelper.isDexMetadataFile(file)) return false; + if (com.android.art.flags.Flags.artServiceV3()) { + if (ArtManagedInstallFileHelper.isArtManaged(file.getPath())) return false; + } else { + if (DexMetadataHelper.isDexMetadataFile(file)) return false; + } if (VerityUtils.isFsveritySignatureFile(file)) return false; if (ApkChecksums.isDigestOrDigestSignatureFile(file)) return false; return true; @@ -872,6 +878,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { return true; } }; + private static final FileFilter sArtManagedFilter = new FileFilter() { + @Override + public boolean accept(File file) { + return !file.isDirectory() && com.android.art.flags.Flags.artServiceV3() + && ArtManagedInstallFileHelper.isArtManaged(file.getPath()); + } + }; static boolean isDataLoaderInstallation(SessionParams params) { return params.dataLoaderParams != null; @@ -1586,6 +1599,19 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } @GuardedBy("mLock") + private List<String> getArtManagedFilePathsLocked() { + String[] names = getNamesLocked(); + ArrayList<String> result = new ArrayList<>(names.length); + for (String name : names) { + File file = new File(stageDir, name); + if (sArtManagedFilter.accept(file)) { + result.add(file.getPath()); + } + } + return result; + } + + @GuardedBy("mLock") private void enableFsVerityToAddedApksWithIdsig() throws PackageManagerException { try { List<File> files = getAddedApksLocked(); @@ -3377,7 +3403,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } final File targetFile = new File(stageDir, targetName); - resolveAndStageFileLocked(addedFile, targetFile, null); + resolveAndStageFileLocked(addedFile, targetFile, null, List.of() /* artManagedFilePaths */); mResolvedBaseFile = targetFile; // Populate package name of the apex session @@ -3470,6 +3496,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { TextUtils.formatSimple("Session: %d. No packages staged in %s", sessionId, stageDir.getAbsolutePath())); } + final List<String> artManagedFilePaths = getArtManagedFilePathsLocked(); // Verify that all staged packages are internally consistent final ArraySet<String> stagedSplits = new ArraySet<>(); @@ -3526,7 +3553,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final File targetFile = new File(stageDir, targetName); if (!isArchivedInstallation()) { final File sourceFile = new File(apk.getPath()); - resolveAndStageFileLocked(sourceFile, targetFile, apk.getSplitName()); + resolveAndStageFileLocked( + sourceFile, targetFile, apk.getSplitName(), artManagedFilePaths); } // Base is coming from session @@ -3687,7 +3715,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // Inherit base if not overridden. if (mResolvedBaseFile == null) { mResolvedBaseFile = new File(appInfo.getBaseCodePath()); - inheritFileLocked(mResolvedBaseFile); + inheritFileLocked(mResolvedBaseFile, artManagedFilePaths); // Collect the requiredSplitTypes from base CollectionUtils.addAll(requiredSplitTypes, existing.getBaseRequiredSplitTypes()); } else if ((params.installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { @@ -3706,7 +3734,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final boolean splitRemoved = removeSplitList.contains(splitName); final boolean splitReplaced = stagedSplits.contains(splitName); if (!splitReplaced && !splitRemoved) { - inheritFileLocked(splitFile); + inheritFileLocked(splitFile, artManagedFilePaths); // Collect the requiredSplitTypes and staged splitTypes from splits CollectionUtils.addAll(requiredSplitTypes, existing.getRequiredSplitTypes()[i]); @@ -3892,6 +3920,23 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { DexMetadataHelper.isFsVerityRequired()); } + @FlaggedApi(com.android.art.flags.Flags.FLAG_ART_SERVICE_V3) + @GuardedBy("mLock") + private void maybeStageArtManagedInstallFilesLocked(File origFile, File targetFile, + List<String> artManagedFilePaths) throws PackageManagerException { + for (String path : ArtManagedInstallFileHelper.filterPathsForApk( + artManagedFilePaths, origFile.getPath())) { + File artManagedFile = new File(path); + if (!FileUtils.isValidExtFilename(artManagedFile.getName())) { + throw new PackageManagerException( + INSTALL_FAILED_INVALID_APK, "Invalid filename: " + artManagedFile); + } + File targetArtManagedFile = new File( + ArtManagedInstallFileHelper.getTargetPathForApk(path, targetFile.getPath())); + stageFileLocked(artManagedFile, targetArtManagedFile); + } + } + private IncrementalFileStorages getIncrementalFileStorages() { synchronized (mLock) { return mIncrementalFileStorages; @@ -3989,8 +4034,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } @GuardedBy("mLock") - private void resolveAndStageFileLocked(File origFile, File targetFile, String splitName) - throws PackageManagerException { + private void resolveAndStageFileLocked(File origFile, File targetFile, String splitName, + List<String> artManagedFilePaths) throws PackageManagerException { stageFileLocked(origFile, targetFile); // Stage APK's fs-verity signature if present. @@ -4001,8 +4046,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { && VerityUtils.isFsVeritySupported()) { maybeStageV4SignatureLocked(origFile, targetFile); } - // Stage dex metadata (.dm) and corresponding fs-verity signature if present. - maybeStageDexMetadataLocked(origFile, targetFile); + // Stage ART managed install files (e.g., dex metadata (.dm)) and corresponding fs-verity + // signature if present. + if (com.android.art.flags.Flags.artServiceV3()) { + maybeStageArtManagedInstallFilesLocked(origFile, targetFile, artManagedFilePaths); + } else { + maybeStageDexMetadataLocked(origFile, targetFile); + } // Stage checksums (.digests) if present. maybeStageDigestsLocked(origFile, targetFile, splitName); } @@ -4027,7 +4077,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } @GuardedBy("mLock") - private void inheritFileLocked(File origFile) { + private void inheritFileLocked(File origFile, List<String> artManagedFilePaths) { mResolvedInheritedFiles.add(origFile); maybeInheritFsveritySignatureLocked(origFile); @@ -4035,12 +4085,20 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { maybeInheritV4SignatureLocked(origFile); } - // Inherit the dex metadata if present. - final File dexMetadataFile = - DexMetadataHelper.findDexMetadataForFile(origFile); - if (dexMetadataFile != null) { - mResolvedInheritedFiles.add(dexMetadataFile); - maybeInheritFsveritySignatureLocked(dexMetadataFile); + // Inherit ART managed install files (e.g., dex metadata (.dm)) if present. + if (com.android.art.flags.Flags.artServiceV3()) { + for (String path : ArtManagedInstallFileHelper.filterPathsForApk( + artManagedFilePaths, origFile.getPath())) { + File artManagedFile = new File(path); + mResolvedInheritedFiles.add(artManagedFile); + maybeInheritFsveritySignatureLocked(artManagedFile); + } + } else { + final File dexMetadataFile = DexMetadataHelper.findDexMetadataForFile(origFile); + if (dexMetadataFile != null) { + mResolvedInheritedFiles.add(dexMetadataFile); + maybeInheritFsveritySignatureLocked(dexMetadataFile); + } } // Inherit the digests if present. final File digestsFile = ApkChecksums.findDigestsForFile(origFile); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorValidationTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorValidationTest.java index 644ae4717eb1..1ba202b717c4 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorValidationTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorValidationTest.java @@ -29,8 +29,6 @@ import android.os.UserHandle; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; -import android.platform.test.flag.junit.RavenwoodFlagsValueProvider; -import android.platform.test.ravenwood.RavenwoodRule; import android.provider.DeviceConfig; import androidx.test.InstrumentationRegistry; @@ -59,13 +57,8 @@ import java.util.regex.Pattern; @LargeTest @android.platform.test.annotations.DisabledOnRavenwood(reason = "Integration test") public class CpuPowerStatsCollectorValidationTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule(); - - @Rule(order = 1) - public final CheckFlagsRule mCheckFlagsRule = RavenwoodRule.isOnRavenwood() - ? RavenwoodFlagsValueProvider.createAllOnCheckFlagsRule() - : DeviceFlagsValueProvider.createCheckFlagsRule(); + @Rule + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); private static final int WORK_DURATION_MS = 2000; private static final String TEST_PKG = "com.android.coretests.apps.bstatstestapp"; diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/SystemServicePowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/SystemServicePowerCalculatorTest.java index ef0b570a1354..1ff347f93da2 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/SystemServicePowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/SystemServicePowerCalculatorTest.java @@ -31,8 +31,6 @@ import android.os.Process; import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; -import android.platform.test.flag.junit.RavenwoodFlagsValueProvider; -import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; @@ -58,18 +56,13 @@ import java.util.Collection; @SuppressWarnings("GuardedBy") public class SystemServicePowerCalculatorTest { @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule(); - - @Rule(order = 1) - public final CheckFlagsRule mCheckFlagsRule = RavenwoodRule.isOnRavenwood() - ? RavenwoodFlagsValueProvider.createAllOnCheckFlagsRule() - : DeviceFlagsValueProvider.createCheckFlagsRule(); + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); private static final double PRECISION = 0.000001; private static final int APP_UID1 = 100; private static final int APP_UID2 = 200; - @Rule(order = 2) + @Rule(order = 1) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_CPU_ACTIVE, 720) .setCpuScalingPolicy(0, new int[]{0, 1}, new int[]{100, 200}) |