Merge "[Ravenwood] Prevent dexmaker from going into Ravenwood tests" into main
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 84f2ab2..9a294fd 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -597,6 +597,7 @@
 
   public class TelephonyManager {
     method @NonNull public static int[] getAllNetworkTypes();
+    method @FlaggedApi("android.os.mainline_vcn_platform_api") @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Set<java.lang.String> getPackagesWithCarrierPrivileges();
   }
 
 }
diff --git a/services/profcollect/src/com/android/server/profcollect/Utils.java b/services/profcollect/src/com/android/server/profcollect/Utils.java
index b4e2544..a8016a0 100644
--- a/services/profcollect/src/com/android/server/profcollect/Utils.java
+++ b/services/profcollect/src/com/android/server/profcollect/Utils.java
@@ -25,10 +25,14 @@
 
 import com.android.internal.os.BackgroundThread;
 
+import java.time.Instant;
 import java.util.concurrent.ThreadLocalRandom;
 
 public final class Utils {
 
+    private static Instant lastTraceTime = Instant.EPOCH;
+    private static final int TRACE_COOLDOWN_SECONDS = 30;
+
     public static boolean withFrequency(String configName, int defaultFrequency) {
         int threshold = DeviceConfig.getInt(
                 DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT, configName, defaultFrequency);
@@ -40,6 +44,9 @@
         if (mIProfcollect == null) {
             return false;
         }
+        if (isInCooldownOrReset()) {
+            return false;
+        }
         BackgroundThread.get().getThreadHandler().post(() -> {
             try {
                 mIProfcollect.trace_system(eventName);
@@ -54,6 +61,9 @@
         if (mIProfcollect == null) {
             return false;
         }
+        if (isInCooldownOrReset()) {
+            return false;
+        }
         BackgroundThread.get().getThreadHandler().postDelayed(() -> {
             try {
                 mIProfcollect.trace_system(eventName);
@@ -69,6 +79,9 @@
         if (mIProfcollect == null) {
             return false;
         }
+        if (isInCooldownOrReset()) {
+            return false;
+        }
         BackgroundThread.get().getThreadHandler().post(() -> {
             try {
                 mIProfcollect.trace_process(eventName,
@@ -80,4 +93,16 @@
         });
         return true;
     }
+
+    /**
+     * Returns true if the last trace is within the cooldown period. If the last trace is outside
+     * the cooldown period, the last trace time is reset to the current time.
+     */
+    private static boolean isInCooldownOrReset() {
+        if (!Instant.now().isBefore(lastTraceTime.plusSeconds(TRACE_COOLDOWN_SECONDS))) {
+            lastTraceTime = Instant.now();
+            return false;
+        }
+        return true;
+    }
 }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index dbe4f27..609449f 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -10586,20 +10586,31 @@
         return null;
     }
 
-    /** @hide */
+    /**
+     * Get the names of packages with carrier privileges for the current subscription.
+     *
+     * @throws UnsupportedOperationException If the device does not have {@link
+     *     PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}
+     * @hide
+     */
+    @FlaggedApi(android.os.Flags.FLAG_MAINLINE_VCN_PLATFORM_API)
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public List<String> getPackagesWithCarrierPrivileges() {
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+    @NonNull
+    public Set<String> getPackagesWithCarrierPrivileges() {
+        final Set<String> result = new HashSet<>();
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.getPackagesWithCarrierPrivileges(getPhoneId());
+                result.addAll(telephony.getPackagesWithCarrierPrivileges(getPhoneId()));
             }
         } catch (RemoteException ex) {
             Rlog.e(TAG, "getPackagesWithCarrierPrivileges RemoteException", ex);
         } catch (NullPointerException ex) {
             Rlog.e(TAG, "getPackagesWithCarrierPrivileges NPE", ex);
         }
-        return Collections.EMPTY_LIST;
+        return result;
     }
 
     /**
diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
index b5cc553..f1f74bc 100644
--- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
@@ -206,7 +206,7 @@
                 .getAllSubscriptionInfoList();
 
         doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt());
-        setPrivilegedPackagesForMock(Collections.singletonList(PACKAGE_NAME));
+        setPrivilegedPackagesForMock(Collections.singleton(PACKAGE_NAME));
     }
 
     private IntentFilter getIntentFilter() {
@@ -293,7 +293,7 @@
                 Collections.singletonMap(TEST_SUBSCRIPTION_ID_1, TEST_CARRIER_CONFIG_WRAPPER));
     }
 
-    private void setPrivilegedPackagesForMock(@NonNull List<String> privilegedPackages) {
+    private void setPrivilegedPackagesForMock(@NonNull Set<String> privilegedPackages) {
         doReturn(privilegedPackages).when(mTelephonyManager).getPackagesWithCarrierPrivileges();
     }
 
@@ -390,7 +390,7 @@
     @Test
     public void testOnSubscriptionsChangedFired_onActiveSubIdsChanged() throws Exception {
         setupReadySubIds();
-        setPrivilegedPackagesForMock(Collections.emptyList());
+        setPrivilegedPackagesForMock(Collections.emptySet());
 
         doReturn(TEST_SUBSCRIPTION_ID_2).when(mDeps).getActiveDataSubscriptionId();
         final ActiveDataSubscriptionIdListener listener = getActiveDataSubscriptionIdListener();
@@ -411,7 +411,7 @@
     public void testOnSubscriptionsChangedFired_WithReadySubidsNoPrivilegedPackages()
             throws Exception {
         setupReadySubIds();
-        setPrivilegedPackagesForMock(Collections.emptyList());
+        setPrivilegedPackagesForMock(Collections.emptySet());
 
         final OnSubscriptionsChangedListener listener = getOnSubscriptionsChangedListener();
         listener.onSubscriptionsChanged();
@@ -567,7 +567,7 @@
         verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES)));
 
         // Simulate a loss of carrier privileges
-        setPrivilegedPackagesForMock(Collections.emptyList());
+        setPrivilegedPackagesForMock(Collections.emptySet());
         listener.onSubscriptionsChanged();
         mTestLooper.dispatchAll();