Merge "Fix NullPointerException in android.widget.TimePickerSpinnerDelegate.updateInputState" into main
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 02e8eec..e680103 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -262,6 +262,7 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/InProcessTethering)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/OsuLogin)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system_other/system/app/OsuLogin)
+$(call add-clean-step, rm -rf $(OUT_DIR)/host/linux-x86/testcases/ravenwood-runtime)
 # ******************************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
 # ******************************************************************
diff --git a/OWNERS b/OWNERS
index 7ceca32..bde7ab2 100644
--- a/OWNERS
+++ b/OWNERS
@@ -28,7 +28,7 @@
 # Support bulk translation updates
 per-file */res*/values*/*.xml = byi@google.com, delphij@google.com
 
-per-file **.bp,**.mk = hansson@google.com, joeo@google.com, lamontjones@google.com
+per-file **.bp,**.mk =joeo@google.com, lamontjones@google.com
 per-file TestProtoLibraries.bp = file:platform/platform_testing:/libraries/health/OWNERS
 per-file TestProtoLibraries.bp = file:platform/tools/tradefederation:/OWNERS
 
diff --git a/Ravenwood.bp b/Ravenwood.bp
index f43c37b..912f19d 100644
--- a/Ravenwood.bp
+++ b/Ravenwood.bp
@@ -30,7 +30,7 @@
     name: "framework-minus-apex.ravenwood-base",
     tools: ["hoststubgen"],
     cmd: "$(location hoststubgen) " +
-        "@$(location ravenwood/ravenwood-standard-options.txt) " +
+        "@$(location :ravenwood-standard-options) " +
 
         "--debug-log $(location hoststubgen_framework-minus-apex.log) " +
         "--stats-file $(location hoststubgen_framework-minus-apex_stats.csv) " +
@@ -41,13 +41,13 @@
         "--gen-input-dump-file $(location hoststubgen_dump.txt) " +
 
         "--in-jar $(location :framework-minus-apex-for-hoststubgen) " +
-        "--policy-override-file $(location ravenwood/framework-minus-apex-ravenwood-policies.txt) " +
-        "--annotation-allowed-classes-file $(location ravenwood/ravenwood-annotation-allowed-classes.txt) ",
+        "--policy-override-file $(location :ravenwood-framework-policies) " +
+        "--annotation-allowed-classes-file $(location :ravenwood-annotation-allowed-classes) ",
     srcs: [
         ":framework-minus-apex-for-hoststubgen",
-        "ravenwood/framework-minus-apex-ravenwood-policies.txt",
-        "ravenwood/ravenwood-standard-options.txt",
-        "ravenwood/ravenwood-annotation-allowed-classes.txt",
+        ":ravenwood-framework-policies",
+        ":ravenwood-standard-options",
+        ":ravenwood-annotation-allowed-classes",
     ],
     out: [
         "ravenwood.jar",
@@ -91,7 +91,7 @@
     name: "services.core.ravenwood-base",
     tools: ["hoststubgen"],
     cmd: "$(location hoststubgen) " +
-        "@$(location ravenwood/ravenwood-standard-options.txt) " +
+        "@$(location :ravenwood-standard-options) " +
 
         "--debug-log $(location hoststubgen_services.core.log) " +
         "--stats-file $(location hoststubgen_services.core_stats.csv) " +
@@ -102,13 +102,13 @@
         "--gen-input-dump-file $(location hoststubgen_dump.txt) " +
 
         "--in-jar $(location :services.core-for-hoststubgen) " +
-        "--policy-override-file $(location ravenwood/services.core-ravenwood-policies.txt) " +
-        "--annotation-allowed-classes-file $(location ravenwood/ravenwood-annotation-allowed-classes.txt) ",
+        "--policy-override-file $(location :ravenwood-services-policies) " +
+        "--annotation-allowed-classes-file $(location :ravenwood-annotation-allowed-classes) ",
     srcs: [
         ":services.core-for-hoststubgen",
-        "ravenwood/services.core-ravenwood-policies.txt",
-        "ravenwood/ravenwood-standard-options.txt",
-        "ravenwood/ravenwood-annotation-allowed-classes.txt",
+        ":ravenwood-services-policies",
+        ":ravenwood-standard-options",
+        ":ravenwood-annotation-allowed-classes",
     ],
     out: [
         "ravenwood.jar",
@@ -137,6 +137,7 @@
 
 java_library {
     name: "services.core.ravenwood-jarjar",
+    defaults: ["ravenwood-internal-only-visibility-java"],
     installable: false,
     static_libs: [
         "services.core.ravenwood",
@@ -144,88 +145,29 @@
     jarjar_rules: ":ravenwood-services-jarjar-rules",
 }
 
-java_library {
-    name: "services.fakes.ravenwood-jarjar",
-    installable: false,
-    srcs: [":services.fakes-sources"],
-    libs: [
-        "ravenwood-framework",
-        "services.core.ravenwood",
-    ],
-    jarjar_rules: ":ravenwood-services-jarjar-rules",
-}
-
-java_library {
-    name: "mockito-ravenwood-prebuilt",
-    installable: false,
-    static_libs: [
-        "mockito-robolectric-prebuilt",
-    ],
-}
-
-java_library {
-    name: "inline-mockito-ravenwood-prebuilt",
-    installable: false,
-    static_libs: [
-        "inline-mockito-robolectric-prebuilt",
-    ],
-}
-
 // Jars in "ravenwood-runtime" are set to the classpath, sorted alphabetically.
 // Rename some of the dependencies to make sure they're included in the intended order.
 java_genrule {
     name: "100-framework-minus-apex.ravenwood",
+    defaults: ["ravenwood-internal-only-visibility-genrule"],
     cmd: "cp $(in) $(out)",
     srcs: [":framework-minus-apex.ravenwood"],
     out: ["100-framework-minus-apex.ravenwood.jar"],
-    visibility: ["//visibility:private"],
 }
 
 java_genrule {
     // Use 200 to make sure it comes before the mainline stub ("all-updatable...").
     name: "200-kxml2-android",
+    defaults: ["ravenwood-internal-only-visibility-genrule"],
     cmd: "cp $(in) $(out)",
     srcs: [":kxml2-android"],
     out: ["200-kxml2-android.jar"],
-    visibility: ["//visibility:private"],
 }
 
-android_ravenwood_libgroup {
-    name: "ravenwood-runtime",
-    libs: [
-        "100-framework-minus-apex.ravenwood",
-        "200-kxml2-android",
-        "all-updatable-modules-system-stubs",
-        "android.test.mock.ravenwood",
-        "ravenwood-helper-runtime",
-        "hoststubgen-helper-runtime.ravenwood",
-        "services.core.ravenwood-jarjar",
-        "services.fakes.ravenwood-jarjar",
-
-        // Provide runtime versions of utils linked in below
-        "junit",
-        "truth",
-        "flag-junit",
-        "ravenwood-framework",
-        "ravenwood-junit-impl",
-        "ravenwood-junit-impl-flag",
-        "mockito-ravenwood-prebuilt",
-        "inline-mockito-ravenwood-prebuilt",
-    ],
-    jni_libs: [
-        "libandroid_runtime",
-    ],
-}
-
-android_ravenwood_libgroup {
-    name: "ravenwood-utils",
-    libs: [
-        "junit",
-        "truth",
-        "flag-junit",
-        "ravenwood-framework",
-        "ravenwood-junit",
-        "mockito-ravenwood-prebuilt",
-        "inline-mockito-ravenwood-prebuilt",
-    ],
+java_genrule {
+    name: "z00-all-updatable-modules-system-stubs",
+    defaults: ["ravenwood-internal-only-visibility-genrule"],
+    cmd: "cp $(in) $(out)",
+    srcs: [":all-updatable-modules-system-stubs"],
+    out: ["z00-all-updatable-modules-system-stubs.jar"],
 }
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/CipherEncryptPerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/CipherEncryptPerfTest.java
index c69ae39..36266de 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/CipherEncryptPerfTest.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/CipherEncryptPerfTest.java
@@ -23,6 +23,9 @@
 import org.conscrypt.TestUtils;
 
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
 import java.security.Key;
 import java.security.NoSuchAlgorithmException;
 import javax.crypto.Cipher;
@@ -91,21 +94,17 @@
         }
     }
 
-    private Object[] getParams() {
-        return new Object[][] {
-            new Object[] {new Config(BufferType.ARRAY,
-                              MyCipherFactory.CONSCRYPT,
-                              Transformation.AES_CBC_PKCS5)},
-            new Object[] {new Config(BufferType.ARRAY,
-                              MyCipherFactory.CONSCRYPT,
-                              Transformation.AES_ECB_PKCS5)},
-            new Object[] {new Config(BufferType.ARRAY,
-                              MyCipherFactory.CONSCRYPT,
-                              Transformation.AES_GCM_NO)},
-            new Object[] {new Config(BufferType.ARRAY,
-                              MyCipherFactory.CONSCRYPT,
-                              Transformation.AES_GCM_SIV)},
-        };
+    public Collection <Object[]> getParams() {
+        final List<Object[]> params = new ArrayList<>();
+        for (BufferType bufferType : BufferType.values()) {
+            for (CipherFactory cipherFactory : MyCipherFactory.values()) {
+                for (Transformation transformation : Transformation.values()) {
+                  params.add(new Object[] {new Config(
+                                bufferType, cipherFactory, transformation)});
+                }
+            }
+        }
+        return params;
     }
 
     private EncryptStrategy encryptStrategy;
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java
index dd9f4eb..2643bae 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java
@@ -30,6 +30,9 @@
 import java.io.OutputStream;
 import java.net.SocketException;
 import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
@@ -104,19 +107,26 @@
         }
     }
 
-    private Object[] getParams() {
-        return new Object[][] {
-            new Object[] {new Config(
-                              EndpointFactory.CONSCRYPT,
-                              EndpointFactory.CONSCRYPT,
-                              64,
-                              "AES128-GCM",
-                              ChannelType.CHANNEL,
-                              PerfTestProtocol.TLSv13)},
-        };
+    public Collection getParams() {
+        final List<Object[]> params = new ArrayList<>();
+        for (EndpointFactory endpointFactory : EndpointFactory.values()) {
+            for (ChannelType channelType : ChannelType.values()) {
+                for (PerfTestProtocol protocol : PerfTestProtocol.values()) {
+                    params.add(new Object[] {new Config(endpointFactory,
+                        endpointFactory, 64, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+                        channelType, protocol)});
+                    params.add(new Object[] {new Config(endpointFactory,
+                        endpointFactory, 512, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+                        channelType, protocol)});
+                    params.add(new Object[] {new Config(endpointFactory,
+                        endpointFactory, 4096, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+                        channelType, protocol)});
+                }
+            }
+        }
+        return params;
     }
 
-
     private ClientEndpoint client;
     private ServerEndpoint server;
     private byte[] message;
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineFactory.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineFactory.java
new file mode 100644
index 0000000..8a0d52d
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineFactory.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2017 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 android.conscrypt;
+
+import org.conscrypt.TestUtils;
+import java.security.Security;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+
+
+/**
+ * Factory for {@link SSLEngine} instances.
+ */
+public class EngineFactory {
+    public EngineFactory() {
+        this(newConscryptClientContext(), newConscryptServerContext());
+    }
+
+    private EngineFactory(SSLContext clientContext, SSLContext serverContext) {
+        this.clientContext = clientContext;
+        this.serverContext = serverContext;
+    }
+
+    private final SSLContext clientContext;
+    private final SSLContext serverContext;
+
+    public SSLEngine newClientEngine(String cipher) {
+        SSLEngine engine = initEngine(clientContext.createSSLEngine(), cipher, true);
+        return engine;
+    }
+
+    public SSLEngine newServerEngine(String cipher) {
+        SSLEngine engine = initEngine(serverContext.createSSLEngine(), cipher, false);
+        return engine;
+    }
+
+    public void dispose(SSLEngine engine) {
+        engine.closeOutbound();
+    }
+
+    private static SSLContext newConscryptClientContext() {
+        return TestUtils.newClientSslContext(TestUtils.getConscryptProvider());
+    }
+
+    private static SSLContext newConscryptServerContext() {
+        return TestUtils.newServerSslContext(TestUtils.getConscryptProvider());
+    }
+
+    static SSLEngine initEngine(SSLEngine engine, String cipher, boolean client) {
+        engine.setEnabledProtocols(new String[]{"TLSv1.2", "TLSv1.3"});
+        engine.setEnabledCipherSuites(new String[] {cipher});
+        engine.setUseClientMode(client);
+        return engine;
+    }
+}
\ No newline at end of file
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineHandshakePerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineHandshakePerfTest.java
new file mode 100644
index 0000000..cd0ac96
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineHandshakePerfTest.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2017 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.
+ */
+
+/*
+ * Copyright 2017 The Netty Project
+ *
+ * The Netty Project licenses this file to you 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 android.conscrypt;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLException;
+
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import androidx.test.filters.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Benchmark comparing handshake performance of various engine implementations to conscrypt.
+ */
+@RunWith(JUnitParamsRunner.class)
+@LargeTest
+public final class EngineHandshakePerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    /**
+     * Provider for the test configuration
+     */
+    private class Config {
+        BufferType a_bufferType;
+        String c_cipher;
+        int d_rttMillis;
+        Config(BufferType bufferType,
+            String cipher,
+            int rttMillis) {
+          a_bufferType = bufferType;
+          c_cipher = cipher;
+          d_rttMillis = rttMillis;
+        }
+        public BufferType bufferType() {
+            return a_bufferType;
+        }
+
+        public String cipher() {
+            return c_cipher;
+        }
+
+        public int rttMillis() {
+            return d_rttMillis;
+        }
+    }
+
+    public Collection getParams() {
+        final List<Object[]> params = new ArrayList<>();
+        for (BufferType bufferType : BufferType.values()) {
+            params.add(new Object[] {new Config(bufferType,
+                "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 100)});
+        }
+        return params;
+    }
+
+    private static final ByteBuffer EMPTY_BUFFER = ByteBuffer.allocateDirect(0);
+
+    private EngineFactory engineFactory = new EngineFactory();
+    private String cipher;
+    private int rttMillis;
+
+    private ByteBuffer clientApplicationBuffer;
+    private ByteBuffer clientPacketBuffer;
+    private ByteBuffer serverApplicationBuffer;
+    private ByteBuffer serverPacketBuffer;
+
+    private void setup(Config config) throws Exception {
+        cipher = config.cipher();
+        rttMillis = config.rttMillis();
+        BufferType bufferType = config.bufferType();
+
+        SSLEngine clientEngine = engineFactory.newClientEngine(cipher);
+        SSLEngine serverEngine = engineFactory.newServerEngine(cipher);
+
+        // Create the application and packet buffers for both endpoints.
+        clientApplicationBuffer = bufferType.newApplicationBuffer(clientEngine);
+        serverApplicationBuffer = bufferType.newApplicationBuffer(serverEngine);
+        clientPacketBuffer = bufferType.newPacketBuffer(clientEngine);
+        serverPacketBuffer = bufferType.newPacketBuffer(serverEngine);
+
+        engineFactory.dispose(clientEngine);
+        engineFactory.dispose(serverEngine);
+    }
+
+    @Test
+    @Parameters(method = "getParams")
+    public void handshake(Config config) throws Exception {
+        setup(config);
+        SSLEngine client = engineFactory.newClientEngine(cipher);
+        SSLEngine server = engineFactory.newServerEngine(cipher);
+        clientApplicationBuffer.clear();
+        clientPacketBuffer.clear();
+        serverApplicationBuffer.clear();
+        serverPacketBuffer.clear();
+
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            client.beginHandshake();
+            server.beginHandshake();
+            doHandshake(client, server);
+        }
+
+        engineFactory.dispose(client);
+        engineFactory.dispose(server);
+    }
+
+    private void doHandshake(SSLEngine client, SSLEngine server) throws SSLException {
+
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            // Send as many client-to-server messages as possible
+            doHalfHandshake(client, server, clientPacketBuffer, serverApplicationBuffer);
+
+            if (client.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING
+                    && server.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING) {
+                return;
+            }
+
+            // Do the same with server-to-client messages
+            doHalfHandshake(server, client, serverPacketBuffer, clientApplicationBuffer);
+
+            if (client.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING
+                    && server.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING) {
+                return;
+            }
+        }
+    }
+
+    private void doHalfHandshake(SSLEngine sender, SSLEngine receiver,
+            ByteBuffer senderPacketBuffer, ByteBuffer receiverApplicationBuffer)
+            throws SSLException {
+        SSLEngineResult senderResult;
+        SSLEngineResult receiverResult;
+
+        do {
+            senderResult = sender.wrap(EMPTY_BUFFER, senderPacketBuffer);
+            runDelegatedTasks(senderResult, sender);
+            senderPacketBuffer.flip();
+            receiverResult = receiver.unwrap(senderPacketBuffer, receiverApplicationBuffer);
+            runDelegatedTasks(receiverResult, receiver);
+            senderPacketBuffer.compact();
+        } while (senderResult.getHandshakeStatus() == HandshakeStatus.NEED_WRAP);
+
+        if (rttMillis > 0) {
+            try {
+                Thread.sleep(rttMillis / 2);
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private static void runDelegatedTasks(SSLEngineResult result, SSLEngine engine) {
+        if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {
+            for (;;) {
+                Runnable task = engine.getDelegatedTask();
+                if (task == null) {
+                    break;
+                }
+                task.run();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineWrapPerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineWrapPerfTest.java
new file mode 100644
index 0000000..1fee218
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineWrapPerfTest.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2017 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.
+ */
+
+/*
+ * Copyright 2017 The Netty Project
+ *
+ * The Netty Project licenses this file to you 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 android.conscrypt;
+
+import static org.conscrypt.TestUtils.doEngineHandshake;
+import static org.conscrypt.TestUtils.newTextMessage;
+import static org.junit.Assert.assertEquals;
+
+import java.nio.ByteBuffer;
+import java.util.Locale;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import androidx.test.filters.LargeTest;
+
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Benchmark comparing performance of various engine implementations to conscrypt.
+ */
+@RunWith(JUnitParamsRunner.class)
+@LargeTest
+public final class EngineWrapPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    /**
+     * Provider for the benchmark configuration
+     */
+    private class Config {
+        BufferType a_bufferType;
+        int c_messageSize;
+        String d_cipher;
+        Config(BufferType bufferType,
+            int messageSize,
+            String cipher) {
+          a_bufferType = bufferType;
+          c_messageSize = messageSize;
+          d_cipher = cipher;
+        }
+        public BufferType bufferType() {
+            return a_bufferType;
+        }
+
+        public int messageSize() {
+            return c_messageSize;
+        }
+
+        public String cipher() {
+            return d_cipher;
+        }
+    }
+
+    public Collection getParams() {
+        final List<Object[]> params = new ArrayList<>();
+        for (BufferType bufferType : BufferType.values()) {
+            params.add(new Object[] {new Config(bufferType, 64,
+                                    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")});
+            params.add(new Object[] {new Config(bufferType, 512,
+                                    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")});
+            params.add(new Object[] {new Config(bufferType, 4096,
+                                    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")});
+        }
+        return params;
+    }
+
+
+    private EngineFactory engineFactory = new EngineFactory();
+    private String cipher;
+    private SSLEngine clientEngine;
+    private SSLEngine serverEngine;
+
+    private ByteBuffer messageBuffer;
+    private ByteBuffer clientApplicationBuffer;
+    private ByteBuffer clientPacketBuffer;
+    private ByteBuffer serverApplicationBuffer;
+    private ByteBuffer serverPacketBuffer;
+    private ByteBuffer preEncryptedBuffer;
+
+    private void setup(Config config) throws Exception {
+        cipher = config.cipher();
+        BufferType bufferType = config.bufferType();
+
+        clientEngine = engineFactory.newClientEngine(cipher);
+        serverEngine = engineFactory.newServerEngine(cipher);
+
+        // Create the application and packet buffers for both endpoints.
+        clientApplicationBuffer = bufferType.newApplicationBuffer(clientEngine);
+        serverApplicationBuffer = bufferType.newApplicationBuffer(serverEngine);
+        clientPacketBuffer = bufferType.newPacketBuffer(clientEngine);
+        serverPacketBuffer = bufferType.newPacketBuffer(serverEngine);
+
+        // Generate the message to be sent from the client.
+        int messageSize = config.messageSize();
+        messageBuffer = bufferType.newBuffer(messageSize);
+        messageBuffer.put(newTextMessage(messageSize));
+        messageBuffer.flip();
+
+        // Complete the initial TLS handshake.
+        doEngineHandshake(clientEngine, serverEngine, clientApplicationBuffer, clientPacketBuffer,
+                serverApplicationBuffer, serverPacketBuffer, true);
+
+        // Populate the pre-encrypted buffer for use with the unwrap benchmark.
+        preEncryptedBuffer = bufferType.newBuffer(clientEngine.getSession().getPacketBufferSize());
+        doWrap(messageBuffer, preEncryptedBuffer);
+        doUnwrap(preEncryptedBuffer, serverApplicationBuffer);
+    }
+
+    void teardown() {
+        engineFactory.dispose(clientEngine);
+        engineFactory.dispose(serverEngine);
+    }
+
+    @Test
+    @Parameters(method = "getParams")
+    public void wrap(Config config) throws Exception {
+        setup(config);
+
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            // Reset the buffers.
+            messageBuffer.position(0);
+            clientPacketBuffer.clear();
+            // Wrap the original message and create the encrypted data.
+            doWrap(messageBuffer, clientPacketBuffer);
+
+            // Lightweight comparison - just make sure the data length is correct.
+            assertEquals(preEncryptedBuffer.limit(), clientPacketBuffer.limit());
+        }
+        teardown();
+    }
+
+    /**
+     * Simple benchmark that sends a single message from client to server.
+     */
+    @Test
+    @Parameters(method = "getParams")
+    public void wrapAndUnwrap(Config config) throws Exception {
+        setup(config);
+
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            // Reset the buffers.
+            messageBuffer.position(0);
+            clientPacketBuffer.clear();
+            serverApplicationBuffer.clear();
+            // Wrap the original message and create the encrypted data.
+            doWrap(messageBuffer, clientPacketBuffer);
+
+            // Unwrap the encrypted data and get back the original result.
+            doUnwrap(clientPacketBuffer, serverApplicationBuffer);
+
+            // Lightweight comparison - just make sure the unencrypted data length is correct.
+            assertEquals(messageBuffer.limit(), serverApplicationBuffer.limit());
+        }
+        teardown();
+    }
+
+    private void doWrap(ByteBuffer src, ByteBuffer dst) throws SSLException {
+        // Wrap the original message and create the encrypted data.
+        verifyResult(src, clientEngine.wrap(src, dst));
+        dst.flip();
+    }
+
+    private void doUnwrap(ByteBuffer src, ByteBuffer dst) throws SSLException {
+        verifyResult(src, serverEngine.unwrap(src, dst));
+        dst.flip();
+    }
+
+    private void verifyResult(ByteBuffer src, SSLEngineResult result) {
+        if (result.getStatus() != SSLEngineResult.Status.OK) {
+            throw new RuntimeException("Operation returned unexpected result " + result);
+        }
+        if (result.bytesConsumed() != src.limit()) {
+            throw new RuntimeException(
+                    String.format(Locale.US,
+                            "Operation didn't consume all bytes. Expected %d, consumed %d.",
+                            src.limit(), result.bytesConsumed()));
+        }
+    }
+}
\ No newline at end of file
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java
index ba2a65a..4f285ff 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java
@@ -24,6 +24,9 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
@@ -94,15 +97,22 @@
         }
     }
 
-    private Object[] getParams() {
-        return new Object[][] {
-            new Object[] {new Config(
-                              EndpointFactory.CONSCRYPT,
-                              EndpointFactory.CONSCRYPT,
-                              64,
-                              "AES128-GCM",
-                              ChannelType.CHANNEL)},
-        };
+    public Collection getParams() {
+        final List<Object[]> params = new ArrayList<>();
+        for (EndpointFactory endpointFactory : EndpointFactory.values()) {
+            for (ChannelType channelType : ChannelType.values()) {
+                params.add(new Object[] {new Config(endpointFactory,
+                    endpointFactory, 64,
+                    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", channelType)});
+                params.add(new Object[] {new Config(endpointFactory,
+                    endpointFactory, 512,
+                    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", channelType)});
+                params.add(new Object[] {new Config(endpointFactory,
+                    endpointFactory, 4096,
+                    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", channelType)});
+            }
+        }
+        return params;
     }
 
     private ClientEndpoint client;
@@ -121,7 +131,8 @@
         final ChannelType channelType = config.channelType();
 
         server = config.serverFactory().newServer(
-            channelType, config.messageSize(), getCommonProtocolSuites(), ciphers(config));
+            channelType, config.messageSize(),
+            new String[] {"TLSv1.3", "TLSv1.2"}, ciphers(config));
         server.setMessageProcessor(new MessageProcessor() {
             @Override
             public void processMessage(byte[] inMessage, int numBytes, OutputStream os) {
@@ -145,7 +156,8 @@
 
         // Always use the same client for consistency across the benchmarks.
         client = config.clientFactory().newClient(
-                ChannelType.CHANNEL, server.port(), getCommonProtocolSuites(), ciphers(config));
+                ChannelType.CHANNEL, server.port(),
+                new String[] {"TLSv1.3", "TLSv1.2"}, ciphers(config));
         client.start();
 
         // Wait for the initial connection to complete.
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/Transformation.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/Transformation.java
index 78fe732..3542b0a 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/Transformation.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/Transformation.java
@@ -31,7 +31,6 @@
     AES_CBC_PKCS5("AES", "CBC", "PKCS5Padding", new AesKeyGen()),
     AES_ECB_PKCS5("AES", "ECB", "PKCS5Padding", new AesKeyGen()),
     AES_GCM_NO("AES", "GCM", "NoPadding", new AesKeyGen()),
-    AES_GCM_SIV("AES", "GCM_SIV", "NoPadding", new AesKeyGen()),
     RSA_ECB_PKCS1("RSA", "ECB", "PKCS1Padding", new RsaKeyGen());
 
     Transformation(String algorithm, String mode, String padding, KeyGen keyGen) {
diff --git a/core/java/android/os/ServiceManager.java b/core/java/android/os/ServiceManager.java
index 0be2d3e3..e95c6a4 100644
--- a/core/java/android/os/ServiceManager.java
+++ b/core/java/android/os/ServiceManager.java
@@ -277,7 +277,7 @@
             if (service != null) {
                 return service;
             } else {
-                return Binder.allowBlocking(getIServiceManager().checkService(name));
+                return Binder.allowBlocking(getIServiceManager().checkService(name).getBinder());
             }
         } catch (RemoteException e) {
             Log.e(TAG, "error in checkService", e);
@@ -425,7 +425,7 @@
     private static IBinder rawGetService(String name) throws RemoteException {
         final long start = sStatLogger.getTime();
 
-        final IBinder binder = getIServiceManager().getService(name);
+        final IBinder binder = getIServiceManager().getService(name).getBinder();
 
         final int time = (int) sStatLogger.logDurationStat(Stats.GET_SERVICE, start);
 
diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java
index 7b91dd5..6c9a5c7 100644
--- a/core/java/android/os/ServiceManagerNative.java
+++ b/core/java/android/os/ServiceManagerNative.java
@@ -58,12 +58,12 @@
     }
 
     @UnsupportedAppUsage
-    public IBinder getService(String name) throws RemoteException {
+    public Service getService(String name) throws RemoteException {
         // Same as checkService (old versions of servicemanager had both methods).
-        return mServiceManager.checkService(name);
+        return checkService(name);
     }
 
-    public IBinder checkService(String name) throws RemoteException {
+    public Service checkService(String name) throws RemoteException {
         return mServiceManager.checkService(name);
     }
 
diff --git a/core/java/android/service/contextualsearch/OWNERS b/core/java/android/service/contextualsearch/OWNERS
index 463adf4..b723872 100644
--- a/core/java/android/service/contextualsearch/OWNERS
+++ b/core/java/android/service/contextualsearch/OWNERS
@@ -1,3 +1,2 @@
 srazdan@google.com
-volnov@google.com
 hackz@google.com
diff --git a/core/java/android/speech/OWNERS b/core/java/android/speech/OWNERS
index 0f2f8ad..32f4822 100644
--- a/core/java/android/speech/OWNERS
+++ b/core/java/android/speech/OWNERS
@@ -1,4 +1,3 @@
 volnov@google.com
 eugeniom@google.com
 schfan@google.com
-hackz@google.com
diff --git a/core/java/android/view/contentcapture/OWNERS b/core/java/android/view/contentcapture/OWNERS
index e4b0952..9ac273f 100644
--- a/core/java/android/view/contentcapture/OWNERS
+++ b/core/java/android/view/contentcapture/OWNERS
@@ -2,4 +2,3 @@
 
 hackz@google.com
 shivanker@google.com
-volnov@google.com
diff --git a/core/jni/com_android_internal_content_FileSystemUtils.cpp b/core/jni/com_android_internal_content_FileSystemUtils.cpp
index d426f12..6c72544 100644
--- a/core/jni/com_android_internal_content_FileSystemUtils.cpp
+++ b/core/jni/com_android_internal_content_FileSystemUtils.cpp
@@ -87,9 +87,10 @@
     IF_ALOGD() {
         ALOGD("Total number of LOAD segments %zu", programHeaders.size());
 
-        ALOGD("Size before punching holes st_blocks: %" PRIu64
-              ", st_blksize: %d, st_size: %" PRIu64 "",
-              beforePunch.st_blocks, beforePunch.st_blksize,
+        ALOGD("Size before punching holes st_blocks: %" PRIu64 ", st_blksize: %" PRIu64
+              ", st_size: %" PRIu64 "",
+              static_cast<uint64_t>(beforePunch.st_blocks),
+              static_cast<uint64_t>(beforePunch.st_blksize),
               static_cast<uint64_t>(beforePunch.st_size));
     }
 
@@ -193,9 +194,10 @@
             ALOGD("lstat64 failed for filePath %s, error:%d", filePath, errno);
             return false;
         }
-        ALOGD("Size after punching holes st_blocks: %" PRIu64 ", st_blksize: %d, st_size: %" PRIu64
-              "",
-              afterPunch.st_blocks, afterPunch.st_blksize,
+        ALOGD("Size after punching holes st_blocks: %" PRIu64 ", st_blksize: %" PRIu64
+              ", st_size: %" PRIu64 "",
+              static_cast<uint64_t>(afterPunch.st_blocks),
+              static_cast<uint64_t>(afterPunch.st_blksize),
               static_cast<uint64_t>(afterPunch.st_size));
     }
 
@@ -271,8 +273,9 @@
     uint64_t blockSize = beforePunch.st_blksize;
     IF_ALOGD() {
         ALOGD("Extra field length: %hu,  Size before punching holes st_blocks: %" PRIu64
-              ", st_blksize: %d, st_size: %" PRIu64 "",
-              extraFieldLen, beforePunch.st_blocks, beforePunch.st_blksize,
+              ", st_blksize: %" PRIu64 ", st_size: %" PRIu64 "",
+              extraFieldLen, static_cast<uint64_t>(beforePunch.st_blocks),
+              static_cast<uint64_t>(beforePunch.st_blksize),
               static_cast<uint64_t>(beforePunch.st_size));
     }
 
@@ -346,8 +349,9 @@
             return false;
         }
         ALOGD("punchHolesInApk:: Size after punching holes st_blocks: %" PRIu64
-              ", st_blksize: %d, st_size: %" PRIu64 "",
-              afterPunch.st_blocks, afterPunch.st_blksize,
+              ", st_blksize: %" PRIu64 ", st_size: %" PRIu64 "",
+              static_cast<uint64_t>(afterPunch.st_blocks),
+              static_cast<uint64_t>(afterPunch.st_blksize),
               static_cast<uint64_t>(afterPunch.st_size));
     }
     return true;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS
index 7ad68aa..b01b2b7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS
@@ -2,7 +2,6 @@
 atsjenk@google.com
 jorgegil@google.com
 madym@google.com
-nmusgrave@google.com
 pbdr@google.com
 tkachenkoi@google.com
 vaniadesmonda@google.com
diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp
index 178102e..33d3624 100644
--- a/ravenwood/Android.bp
+++ b/ravenwood/Android.bp
@@ -16,6 +16,38 @@
     visibility: ["//visibility:public"],
 }
 
+filegroup {
+    name: "ravenwood-services-policies",
+    srcs: [
+        "texts/ravenwood-services-policies.txt",
+    ],
+    visibility: ["//visibility:public"],
+}
+
+filegroup {
+    name: "ravenwood-framework-policies",
+    srcs: [
+        "texts/ravenwood-framework-policies.txt",
+    ],
+    visibility: ["//visibility:public"],
+}
+
+filegroup {
+    name: "ravenwood-standard-options",
+    srcs: [
+        "texts/ravenwood-standard-options.txt",
+    ],
+    visibility: ["//visibility:public"],
+}
+
+filegroup {
+    name: "ravenwood-annotation-allowed-classes",
+    srcs: [
+        "texts/ravenwood-annotation-allowed-classes.txt",
+    ],
+    visibility: ["//visibility:public"],
+}
+
 java_library {
     name: "ravenwood-annotations-lib",
     srcs: [":ravenwood-annotations"],
@@ -151,6 +183,77 @@
 
 filegroup {
     name: "ravenwood-services-jarjar-rules",
-    srcs: ["ravenwood-services-jarjar-rules.txt"],
+    srcs: ["texts/ravenwood-services-jarjar-rules.txt"],
     visibility: ["//frameworks/base"],
 }
+
+java_library {
+    name: "services.fakes.ravenwood-jarjar",
+    installable: false,
+    srcs: [":services.fakes-sources"],
+    libs: [
+        "ravenwood-framework",
+        "services.core.ravenwood",
+    ],
+    jarjar_rules: ":ravenwood-services-jarjar-rules",
+    visibility: ["//visibility:private"],
+}
+
+java_library {
+    name: "mockito-ravenwood-prebuilt",
+    installable: false,
+    static_libs: [
+        "mockito-robolectric-prebuilt",
+    ],
+}
+
+java_library {
+    name: "inline-mockito-ravenwood-prebuilt",
+    installable: false,
+    static_libs: [
+        "inline-mockito-robolectric-prebuilt",
+    ],
+}
+
+android_ravenwood_libgroup {
+    name: "ravenwood-runtime",
+    libs: [
+        "100-framework-minus-apex.ravenwood",
+        "200-kxml2-android",
+
+        "android.test.mock.ravenwood",
+        "ravenwood-helper-runtime",
+        "hoststubgen-helper-runtime.ravenwood",
+        "services.core.ravenwood-jarjar",
+        "services.fakes.ravenwood-jarjar",
+
+        // Provide runtime versions of utils linked in below
+        "junit",
+        "truth",
+        "flag-junit",
+        "ravenwood-framework",
+        "ravenwood-junit-impl",
+        "ravenwood-junit-impl-flag",
+        "mockito-ravenwood-prebuilt",
+        "inline-mockito-ravenwood-prebuilt",
+
+        // It's a stub, so it should be towards the end.
+        "z00-all-updatable-modules-system-stubs",
+    ],
+    jni_libs: [
+        "libandroid_runtime",
+    ],
+}
+
+android_ravenwood_libgroup {
+    name: "ravenwood-utils",
+    libs: [
+        "junit",
+        "truth",
+        "flag-junit",
+        "ravenwood-framework",
+        "ravenwood-junit",
+        "mockito-ravenwood-prebuilt",
+        "inline-mockito-ravenwood-prebuilt",
+    ],
+}
diff --git a/ravenwood/ravenwood-annotation-allowed-classes.txt b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
similarity index 100%
rename from ravenwood/ravenwood-annotation-allowed-classes.txt
rename to ravenwood/texts/ravenwood-annotation-allowed-classes.txt
diff --git a/ravenwood/framework-minus-apex-ravenwood-policies.txt b/ravenwood/texts/ravenwood-framework-policies.txt
similarity index 100%
rename from ravenwood/framework-minus-apex-ravenwood-policies.txt
rename to ravenwood/texts/ravenwood-framework-policies.txt
diff --git a/ravenwood/ravenwood-services-jarjar-rules.txt b/ravenwood/texts/ravenwood-services-jarjar-rules.txt
similarity index 100%
rename from ravenwood/ravenwood-services-jarjar-rules.txt
rename to ravenwood/texts/ravenwood-services-jarjar-rules.txt
diff --git a/ravenwood/services.core-ravenwood-policies.txt b/ravenwood/texts/ravenwood-services-policies.txt
similarity index 100%
rename from ravenwood/services.core-ravenwood-policies.txt
rename to ravenwood/texts/ravenwood-services-policies.txt
diff --git a/ravenwood/ravenwood-standard-options.txt b/ravenwood/texts/ravenwood-standard-options.txt
similarity index 100%
rename from ravenwood/ravenwood-standard-options.txt
rename to ravenwood/texts/ravenwood-standard-options.txt
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index eb03709..d9926a4 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -150,6 +150,15 @@
     private static final int DEFAULT_MAJOR_USER_IMPACT_LEVEL_THRESHOLD =
             PackageHealthObserverImpact.USER_IMPACT_LEVEL_71;
 
+    // Comma separated list of all packages exempt from user impact level threshold. If a package
+    // in the list is crash looping, all the mitigations including factory reset will be performed.
+    private static final String PACKAGES_EXEMPT_FROM_IMPACT_LEVEL_THRESHOLD =
+            "persist.device_config.configuration.packages_exempt_from_impact_level_threshold";
+
+    // Comma separated list of default packages exempt from user impact level threshold.
+    private static final String DEFAULT_PACKAGES_EXEMPT_FROM_IMPACT_LEVEL_THRESHOLD =
+            "com.android.systemui";
+
     private long mNumberOfNativeCrashPollsRemaining;
 
     private static final int DB_VERSION = 1;
@@ -196,6 +205,8 @@
     private final DeviceConfig.OnPropertiesChangedListener
             mOnPropertyChangedListener = this::onPropertyChanged;
 
+    private final Set<String> mPackagesExemptFromImpactLevelThreshold = new ArraySet<>();
+
     // The set of packages that have been synced with the ExplicitHealthCheckController
     @GuardedBy("mLock")
     private Set<String> mRequestedHealthCheckPackages = new ArraySet<>();
@@ -518,7 +529,7 @@
                               @FailureReasons int failureReason,
                               int currentObserverImpact,
                               int mitigationCount) {
-        if (currentObserverImpact < getUserImpactLevelLimit()) {
+        if (allowMitigations(currentObserverImpact, versionedPackage)) {
             synchronized (mLock) {
                 mLastMitigation = mSystemClock.uptimeMillis();
             }
@@ -526,6 +537,13 @@
         }
     }
 
+    private boolean allowMitigations(int currentObserverImpact,
+            VersionedPackage versionedPackage) {
+        return currentObserverImpact < getUserImpactLevelLimit()
+                || getPackagesExemptFromImpactLevelThreshold().contains(
+                versionedPackage.getPackageName());
+    }
+
     private long getMitigationWindowMs() {
         return SystemProperties.getLong(MITIGATION_WINDOW_MS, DEFAULT_MITIGATION_WINDOW_MS);
     }
@@ -657,6 +675,15 @@
                 DEFAULT_MAJOR_USER_IMPACT_LEVEL_THRESHOLD);
     }
 
+    private Set<String> getPackagesExemptFromImpactLevelThreshold() {
+        if (mPackagesExemptFromImpactLevelThreshold.isEmpty()) {
+            String packageNames = SystemProperties.get(PACKAGES_EXEMPT_FROM_IMPACT_LEVEL_THRESHOLD,
+                    DEFAULT_PACKAGES_EXEMPT_FROM_IMPACT_LEVEL_THRESHOLD);
+            return Set.of(packageNames.split("\\s*,\\s*"));
+        }
+        return mPackagesExemptFromImpactLevelThreshold;
+    }
+
     /** Possible severity values of the user impact of a {@link PackageHealthObserver#execute}. */
     @Retention(SOURCE)
     @IntDef(value = {PackageHealthObserverImpact.USER_IMPACT_LEVEL_0,
diff --git a/services/core/java/com/android/server/net/watchlist/OWNERS b/services/core/java/com/android/server/net/watchlist/OWNERS
index d0c4e55..eef1e46 100644
--- a/services/core/java/com/android/server/net/watchlist/OWNERS
+++ b/services/core/java/com/android/server/net/watchlist/OWNERS
@@ -1,2 +1 @@
-alanstokes@google.com
 simonjw@google.com
diff --git a/services/fakes/Android.bp b/services/fakes/Android.bp
index 148054b..d44bb5a 100644
--- a/services/fakes/Android.bp
+++ b/services/fakes/Android.bp
@@ -16,5 +16,5 @@
         "java/**/*.java",
     ],
     path: "java",
-    visibility: ["//frameworks/base"],
+    visibility: ["//frameworks/base/ravenwood:__subpackages__"],
 }
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index 3ed6ad7..e6dac88 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -398,17 +398,16 @@
                 if (randomNum >= traceFrequency) {
                     return;
                 }
-                // For a small percentage a traces, we collect the initialization behavior.
-                boolean traceInitialization = ThreadLocalRandom.current().nextInt(10) < 1;
-                int traceDelay = traceInitialization ? 0 : 1000;
-                String traceTag = traceInitialization ? "camera_init" : "camera";
-                BackgroundThread.get().getThreadHandler().postDelayed(() -> {
+                final int traceDuration = 5000;
+                final String traceTag = "camera";
+                BackgroundThread.get().getThreadHandler().post(() -> {
                     try {
-                        mIProfcollect.trace_process(traceTag, "android.hardware.camera.provider");
+                        mIProfcollect.trace_process(traceTag, "android.hardware.camera.provider",
+                                traceDuration);
                     } catch (RemoteException e) {
                         Log.e(LOG_TAG, "Failed to initiate trace: " + e.getMessage());
                     }
-                }, traceDelay);
+                });
             }
         }, null);
     }
diff --git a/test-mock/Android.bp b/test-mock/Android.bp
index e29d321..5976657 100644
--- a/test-mock/Android.bp
+++ b/test-mock/Android.bp
@@ -51,10 +51,8 @@
 
 java_library {
     name: "android.test.mock.ravenwood",
+    defaults: ["ravenwood-internal-only-visibility-java"],
     srcs: [":android-test-mock-sources"],
-    visibility: [
-        "//frameworks/base",
-    ],
 }
 
 android_ravenwood_test {
diff --git a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
index 3722fef..c0e90f9 100644
--- a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
@@ -35,6 +35,7 @@
 
 import android.Manifest;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.VersionedPackage;
@@ -77,6 +78,7 @@
 import java.io.File;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -413,6 +415,311 @@
         verify(rescuePartyObserver, never()).executeBootLoopMitigation(2);
     }
 
+    @Test
+    @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+    public void testCrashLoopWithRescuePartyAndRollbackObserver() throws Exception {
+        PackageWatchdog watchdog = createWatchdog();
+        RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog);
+        RollbackPackageHealthObserver rollbackObserver =
+                setUpRollbackPackageHealthObserver(watchdog);
+        VersionedPackage versionedPackageA = new VersionedPackage(APP_A, VERSION_CODE);
+
+        when(mMockPackageManager.getApplicationInfo(anyString(), anyInt())).then(inv -> {
+            ApplicationInfo info = new ApplicationInfo();
+            info.flags |= ApplicationInfo.FLAG_PERSISTENT
+                    | ApplicationInfo.FLAG_SYSTEM;
+            return info;
+        });
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // Mitigation: SCOPED_DEVICE_CONFIG_RESET
+        verify(rescuePartyObserver).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+        verify(rescuePartyObserver, never()).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+        verify(rollbackObserver, never()).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // Mitigation: ALL_DEVICE_CONFIG_RESET
+        verify(rescuePartyObserver).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+        verify(rescuePartyObserver, never()).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
+        verify(rollbackObserver, never()).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // Mitigation: WARM_REBOOT
+        verify(rescuePartyObserver).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
+        verify(rescuePartyObserver, never()).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
+        verify(rollbackObserver, never()).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // Mitigation: Low impact rollback
+        verify(rollbackObserver).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+        verify(rescuePartyObserver, never()).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
+
+        // update available rollbacks to mock rollbacks being applied after the call to
+        // rollbackObserver.execute
+        when(mRollbackManager.getAvailableRollbacks()).thenReturn(
+                List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL));
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // DEFAULT_MAJOR_USER_IMPACT_LEVEL_THRESHOLD reached. No more mitigations applied
+        verify(rescuePartyObserver, never()).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
+        verify(rollbackObserver, never()).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+    public void testCrashLoopWithRescuePartyAndRollbackObserverEnableDeprecateFlagReset()
+            throws Exception {
+        PackageWatchdog watchdog = createWatchdog();
+        RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog);
+        RollbackPackageHealthObserver rollbackObserver =
+                setUpRollbackPackageHealthObserver(watchdog);
+        VersionedPackage versionedPackageA = new VersionedPackage(APP_A, VERSION_CODE);
+
+        when(mMockPackageManager.getApplicationInfo(anyString(), anyInt())).then(inv -> {
+            ApplicationInfo info = new ApplicationInfo();
+            info.flags |= ApplicationInfo.FLAG_PERSISTENT
+                    | ApplicationInfo.FLAG_SYSTEM;
+            return info;
+        });
+
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // Mitigation: WARM_REBOOT
+        verify(rescuePartyObserver).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+        verify(rescuePartyObserver, never()).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+        verify(rollbackObserver, never()).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // Mitigation: Low impact rollback
+        verify(rollbackObserver).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+        verify(rescuePartyObserver, never()).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+
+        // update available rollbacks to mock rollbacks being applied after the call to
+        // rollbackObserver.execute
+        when(mRollbackManager.getAvailableRollbacks()).thenReturn(
+                List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL));
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // DEFAULT_MAJOR_USER_IMPACT_LEVEL_THRESHOLD reached. No more mitigations applied
+        verify(rescuePartyObserver, never()).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+        verify(rollbackObserver, never()).execute(versionedPackageA,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+    public void testCrashLoopSystemUIWithRescuePartyAndRollbackObserver() throws Exception {
+        PackageWatchdog watchdog = createWatchdog();
+        RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog);
+        RollbackPackageHealthObserver rollbackObserver =
+                setUpRollbackPackageHealthObserver(watchdog);
+        String systemUi = "com.android.systemui";
+        VersionedPackage versionedPackageUi = new VersionedPackage(
+                systemUi, VERSION_CODE);
+        RollbackInfo rollbackInfoUi = getRollbackInfo(systemUi, VERSION_CODE, 1,
+                PackageManager.ROLLBACK_USER_IMPACT_LOW);
+        when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_LOW,
+                ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL, rollbackInfoUi));
+
+        when(mMockPackageManager.getApplicationInfo(anyString(), anyInt())).then(inv -> {
+            ApplicationInfo info = new ApplicationInfo();
+            info.flags |= ApplicationInfo.FLAG_PERSISTENT
+                    | ApplicationInfo.FLAG_SYSTEM;
+            return info;
+        });
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // Mitigation: SCOPED_DEVICE_CONFIG_RESET
+        verify(rescuePartyObserver).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+        verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+        verify(rollbackObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // Mitigation: ALL_DEVICE_CONFIG_RESET
+        verify(rescuePartyObserver).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+        verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
+        verify(rollbackObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // Mitigation: WARM_REBOOT
+        verify(rescuePartyObserver).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
+        verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
+        verify(rollbackObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // Mitigation: Low impact rollback
+        verify(rollbackObserver).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+        verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
+        verify(rollbackObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+
+        // update available rollbacks to mock rollbacks being applied after the call to
+        // rollbackObserver.execute
+        when(mRollbackManager.getAvailableRollbacks()).thenReturn(
+                List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL));
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // Mitigation: RESET_SETTINGS_UNTRUSTED_DEFAULTS
+        verify(rescuePartyObserver).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
+        verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 5);
+        verify(rollbackObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // Mitigation: RESET_SETTINGS_UNTRUSTED_CHANGES
+        verify(rescuePartyObserver).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 5);
+        verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 6);
+        verify(rollbackObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // Mitigation: RESET_SETTINGS_TRUSTED_DEFAULTS
+        verify(rescuePartyObserver).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 6);
+        verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 7);
+        verify(rollbackObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // Mitigation: Factory reset. High impact rollbacks are performed only for boot loops.
+        verify(rescuePartyObserver).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 7);
+        verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 8);
+        verify(rollbackObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+    public void testCrashLoopSystemUIWithRescuePartyAndRollbackObserverEnableDeprecateFlagReset()
+            throws Exception {
+        PackageWatchdog watchdog = createWatchdog();
+        RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog);
+        RollbackPackageHealthObserver rollbackObserver =
+                setUpRollbackPackageHealthObserver(watchdog);
+        String systemUi = "com.android.systemui";
+        VersionedPackage versionedPackageUi = new VersionedPackage(
+                systemUi, VERSION_CODE);
+        RollbackInfo rollbackInfoUi = getRollbackInfo(systemUi, VERSION_CODE, 1,
+                PackageManager.ROLLBACK_USER_IMPACT_LOW);
+        when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_LOW,
+                ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL, rollbackInfoUi));
+
+        when(mMockPackageManager.getApplicationInfo(anyString(), anyInt())).then(inv -> {
+            ApplicationInfo info = new ApplicationInfo();
+            info.flags |= ApplicationInfo.FLAG_PERSISTENT
+                    | ApplicationInfo.FLAG_SYSTEM;
+            return info;
+        });
+
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // Mitigation: WARM_REBOOT
+        verify(rescuePartyObserver).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+        verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+        verify(rollbackObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // Mitigation: Low impact rollback
+        verify(rollbackObserver).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+        verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+        verify(rollbackObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+
+        // update available rollbacks to mock rollbacks being applied after the call to
+        // rollbackObserver.execute
+        when(mRollbackManager.getAvailableRollbacks()).thenReturn(
+                List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL));
+
+        raiseFatalFailureAndDispatch(watchdog,
+                Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+        // Mitigation: Factory reset. High impact rollbacks are performed only for boot loops.
+        verify(rescuePartyObserver).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+        verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
+        verify(rollbackObserver, never()).execute(versionedPackageUi,
+                PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+    }
+
     RollbackPackageHealthObserver setUpRollbackPackageHealthObserver(PackageWatchdog watchdog) {
         RollbackPackageHealthObserver rollbackObserver =
                 spy(new RollbackPackageHealthObserver(mSpyContext, mApexManager));
@@ -424,7 +731,6 @@
         watchdog.registerHealthObserver(rollbackObserver);
         return rollbackObserver;
     }
-
     RescuePartyObserver setUpRescuePartyObserver(PackageWatchdog watchdog) {
         setCrashRecoveryPropRescueBootCount(0);
         RescuePartyObserver rescuePartyObserver = spy(RescuePartyObserver.getInstance(mSpyContext));
@@ -686,4 +992,20 @@
         mTestLooper.moveTimeForward(milliSeconds);
         mTestLooper.dispatchAll();
     }
+
+    private void raiseFatalFailureAndDispatch(PackageWatchdog watchdog,
+            List<VersionedPackage> packages, int failureReason) {
+        long triggerFailureCount = watchdog.getTriggerFailureCount();
+        if (failureReason == PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK
+                || failureReason == PackageWatchdog.FAILURE_REASON_NATIVE_CRASH) {
+            triggerFailureCount = 1;
+        }
+        for (int i = 0; i < triggerFailureCount; i++) {
+            watchdog.onPackageFailure(packages, failureReason);
+        }
+        mTestLooper.dispatchAll();
+        if (Flags.recoverabilityDetection()) {
+            moveTimeForwardAndDispatch(watchdog.DEFAULT_MITIGATION_WINDOW_MS);
+        }
+    }
 }