Merge "Remove calls to VMRuntime methods that are no-ops."
diff --git a/api/current.txt b/api/current.txt
index 0176b9b..3ba0dd2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -25137,7 +25137,7 @@
     field public static final long POSITION_UNKNOWN = 576460752303423487L; // 0x7ffffffffffffffL
   }
 
-  public static class MediaItem2.Builder {
+  public static final class MediaItem2.Builder {
     ctor public MediaItem2.Builder();
     method @NonNull public android.media.MediaItem2 build();
     method @NonNull public android.media.MediaItem2.Builder setEndPosition(long);
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 5064d23..445075d 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -616,7 +616,7 @@
     // OS: Q
     ACTION_PANEL_INTERACTION = 1658;
 
-    // ACTION: Show Contextual homepage, log latency in loading cards
+    // ACTION: Show Contextual homepage. Log total loading latency.
     ACTION_CONTEXTUAL_HOME_SHOW = 1662;
 
     // ACTION: Contextual card displays
@@ -649,6 +649,15 @@
     ACTION_ATCSCUC = 1680;
 
     ACTION_ATCHNUC = 1681;
+
+    // ACTION: Individual contextual card loading time
+    ACTION_CONTEXTUAL_CARD_LOAD = 1684;
+
+    //ACTION: Contextual card loading timeout
+    ACTION_CONTEXTUAL_CARD_LOAD_TIMEOUT = 1685;
+
+    //ACTION: Log result for each card's eligibility check
+    ACTION_CONTEXTUAL_CARD_ELIGIBILITY = 1686;
 }
 
 /**
diff --git a/media/apex/java/android/media/MediaItem2.java b/media/apex/java/android/media/MediaItem2.java
index fc0f08e..ff0d43e 100644
--- a/media/apex/java/android/media/MediaItem2.java
+++ b/media/apex/java/android/media/MediaItem2.java
@@ -245,7 +245,7 @@
     /**
      * Builder for {@link MediaItem2}.
      */
-    public static class Builder {
+    public static final class Builder {
         @SuppressWarnings("WeakerAccess") /* synthetic access */
         MediaMetadata mMetadata;
         @SuppressWarnings("WeakerAccess") /* synthetic access */
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 0a6e923..91b161d 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -7078,6 +7078,15 @@
     // Open: Settings will show the conditional when Grayscale mode is on
     SETTINGS_CONDITION_GRAYSCALE_MODE = 1683;
 
+    // ACTION: Individual contextual card loading time
+    ACTION_CONTEXTUAL_CARD_LOAD = 1684;
+
+    //ACTION: Contextual card loading timeout
+    ACTION_CONTEXTUAL_CARD_LOAD_TIMEOUT = 1685;
+
+    //ACTION: Log result for each card's eligibility check
+    ACTION_CONTEXTUAL_CARD_ELIGIBILITY = 1686;
+
     // ---- End Q Constants, all Q constants go above this line ----
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java
index 18c2722..d266635 100644
--- a/services/core/java/com/android/server/RescueParty.java
+++ b/services/core/java/com/android/server/RescueParty.java
@@ -38,9 +38,11 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
+import com.android.server.am.SettingsToPropertiesMapper;
 import com.android.server.utils.FlagNamespaceUtils;
 
 import java.io.File;
+import java.util.Arrays;
 
 /**
  * Utilities to help rescue the system from crash loops. Callers are expected to
@@ -158,6 +160,7 @@
      * opportunity to reset any settings depending on our rescue level.
      */
     public static void onSettingsProviderPublished(Context context) {
+        handleNativeRescuePartyResets();
         executeRescueLevel(context);
     }
 
@@ -176,6 +179,13 @@
         return SystemClock.elapsedRealtime();
     }
 
+    private static void handleNativeRescuePartyResets() {
+        if (SettingsToPropertiesMapper.isNativeFlagsResetPerformed()) {
+            FlagNamespaceUtils.resetDeviceConfig(Settings.RESET_MODE_TRUSTED_DEFAULTS,
+                    Arrays.asList(SettingsToPropertiesMapper.getResetNativeCategories()));
+        }
+    }
+
     /**
      * Escalate to the next rescue level. After incrementing the level you'll
      * probably want to call {@link #executeRescueLevel(Context)}.
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 5da1ce6..194549f 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -16,6 +16,7 @@
 
 package com.android.server.am;
 
+import android.annotation.NonNull;
 import android.content.ContentResolver;
 import android.database.ContentObserver;
 import android.net.Uri;
@@ -167,7 +168,7 @@
      * booting.
      * @return
      */
-    public static String[] getResetNativeCategories() {
+    public static @NonNull String[] getResetNativeCategories() {
         if (!isNativeFlagsResetPerformed()) {
             return new String[0];
         }
diff --git a/services/core/java/com/android/server/utils/FlagNamespaceUtils.java b/services/core/java/com/android/server/utils/FlagNamespaceUtils.java
index f26121e..f8c7447 100644
--- a/services/core/java/com/android/server/utils/FlagNamespaceUtils.java
+++ b/services/core/java/com/android/server/utils/FlagNamespaceUtils.java
@@ -19,6 +19,7 @@
 import android.annotation.Nullable;
 import android.provider.DeviceConfig;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.RescueParty;
 
 import java.util.ArrayList;
@@ -41,20 +42,23 @@
     /**
      * Name of the special namespace in DeviceConfig table used for communicating resets.
      */
-    private static final String NAMESPACE_RESCUE_PARTY = "rescue_party_namespace";
+    @VisibleForTesting
+    public static final String NAMESPACE_RESCUE_PARTY = "rescue_party_namespace";
     /**
      * Flag in the {@link DeviceConfig} in {@link #NAMESPACE_RESCUE_PARTY}, holding all known {@link
      * DeviceConfig} namespaces, as a {@link #DELIMITER} separated String. It's updated after the
      * first time flags are written to the new namespace in the {@link DeviceConfig}.
      */
-    private static final String ALL_KNOWN_NAMESPACES_FLAG = "all_known_namespaces";
+    @VisibleForTesting
+    public static final String ALL_KNOWN_NAMESPACES_FLAG = "all_known_namespaces";
     /**
      * Flag in the {@link DeviceConfig} in {@link #NAMESPACE_RESCUE_PARTY} with integer counter
      * suffix added to it, holding {@link DeviceConfig} namespace value whose flags were recently
      * reset by the {@link RescueParty}. It's updated by {@link RescueParty} every time given
      * namespace flags are reset.
      */
-    private static final String RESET_PLATFORM_PACKAGE_FLAG = "reset_platform_package";
+    @VisibleForTesting
+    public static final String RESET_PLATFORM_PACKAGE_FLAG = "reset_platform_package";
     private static final String DELIMITER = ":";
     /**
      * Maximum value of the counter used in combination with {@link #RESET_PLATFORM_PACKAGE_FLAG}
@@ -97,11 +101,25 @@
      * Reset all namespaces in DeviceConfig with consumed resetMode.
      */
     public static void resetDeviceConfig(int resetMode) {
-        List<String> allKnownNamespaces = getAllKnownDeviceConfigNamespacesList();
-        for (String namespace : allKnownNamespaces) {
+        resetDeviceConfig(resetMode, getAllKnownDeviceConfigNamespacesList());
+    }
+
+    /**
+     * Reset all consumed namespaces in DeviceConfig with consumed resetMode.
+     */
+    public static void resetDeviceConfig(int resetMode, List<String> namespacesList) {
+        for (String namespace : namespacesList) {
             DeviceConfig.resetToDefaults(resetMode, namespace);
         }
-        addToKnownResetNamespaces(allKnownNamespaces);
+        addToKnownResetNamespaces(namespacesList);
+    }
+
+    /**
+     * Resets known reset namespaces flag counter for tests only.
+     */
+    @VisibleForTesting
+    public static void resetKnownResetNamespacesFlagCounterForTest() {
+        sKnownResetNamespacesFlagCounter = -1;
     }
 
     /**
diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
index b13735c..36825af 100644
--- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
@@ -35,9 +35,12 @@
 import android.os.RecoverySystem;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.provider.DeviceConfig;
 import android.provider.Settings;
 
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.server.am.SettingsToPropertiesMapper;
+import com.android.server.utils.FlagNamespaceUtils;
 
 import org.junit.After;
 import org.junit.Before;
@@ -56,6 +59,10 @@
 public class RescuePartyTest {
     private static final int PERSISTENT_APP_UID = 12;
     private static final long CURRENT_NETWORK_TIME_MILLIS = 0L;
+    private static final String FAKE_NATIVE_NAMESPACE1 = "native1";
+    private static final String FAKE_NATIVE_NAMESPACE2 = "native2";
+    private static final String[] FAKE_RESET_NATIVE_NAMESPACES =
+            {FAKE_NATIVE_NAMESPACE1, FAKE_NATIVE_NAMESPACE2};
 
     private MockitoSession mSession;
 
@@ -73,9 +80,11 @@
                 ExtendedMockito.mockitoSession().initMocks(
                         this)
                         .strictness(Strictness.LENIENT)
+                        .spyStatic(DeviceConfig.class)
                         .spyStatic(SystemProperties.class)
                         .spyStatic(Settings.Global.class)
                         .spyStatic(Settings.Secure.class)
+                        .spyStatic(SettingsToPropertiesMapper.class)
                         .spyStatic(RecoverySystem.class)
                         .spyStatic(RescueParty.class)
                         .startMocking();
@@ -121,8 +130,17 @@
                 }
         ).when(() -> SystemProperties.getLong(anyString(), anyLong()));
 
+        // Mock DeviceConfig
+        doAnswer((Answer<Boolean>) invocationOnMock -> true)
+                .when(() -> DeviceConfig.setProperty(anyString(), anyString(), anyString(),
+                        anyBoolean()));
+        doAnswer((Answer<Void>) invocationOnMock -> null)
+                .when(() -> DeviceConfig.resetToDefaults(anyInt(), anyString()));
+
+
         doReturn(CURRENT_NETWORK_TIME_MILLIS).when(() -> RescueParty.getElapsedRealtime());
         RescueParty.resetAllThresholds();
+        FlagNamespaceUtils.resetKnownResetNamespacesFlagCounterForTest();
 
         SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL,
                 Integer.toString(RescueParty.LEVEL_NONE));
@@ -278,10 +296,32 @@
                 SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
     }
 
+    @Test
+    public void testNativeRescuePartyResets() {
+        doReturn(true).when(() -> SettingsToPropertiesMapper.isNativeFlagsResetPerformed());
+        doReturn(FAKE_RESET_NATIVE_NAMESPACES).when(
+                () -> SettingsToPropertiesMapper.getResetNativeCategories());
+
+        RescueParty.onSettingsProviderPublished(mMockContext);
+
+        verify(() -> DeviceConfig.resetToDefaults(Settings.RESET_MODE_TRUSTED_DEFAULTS,
+                FAKE_NATIVE_NAMESPACE1));
+        verify(() -> DeviceConfig.resetToDefaults(Settings.RESET_MODE_TRUSTED_DEFAULTS,
+                FAKE_NATIVE_NAMESPACE2));
+
+        ExtendedMockito.verify(
+                () -> DeviceConfig.setProperty(FlagNamespaceUtils.NAMESPACE_RESCUE_PARTY,
+                        FlagNamespaceUtils.RESET_PLATFORM_PACKAGE_FLAG + 0,
+                        FAKE_NATIVE_NAMESPACE1, /*makeDefault=*/true));
+        ExtendedMockito.verify(
+                () -> DeviceConfig.setProperty(FlagNamespaceUtils.NAMESPACE_RESCUE_PARTY,
+                        FlagNamespaceUtils.RESET_PLATFORM_PACKAGE_FLAG + 1,
+                        FAKE_NATIVE_NAMESPACE2, /*makeDefault=*/true));
+    }
+
     private void verifySettingsResets(int resetMode) {
         verify(() -> Settings.Global.resetToDefaultsAsUser(mMockContentResolver, null,
-                resetMode,
-                UserHandle.USER_SYSTEM));
+                resetMode, UserHandle.USER_SYSTEM));
         verify(() -> Settings.Secure.resetToDefaultsAsUser(eq(mMockContentResolver), isNull(),
                 eq(resetMode), anyInt()));
     }